#include "totalmodel.h"
#include "stdio.h"
#include "handm.h"
#include <json/json.h>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <fstream>
#include <iostream>
#include "ceres/ceres.h"
#include "pose_to_transforms.h"
#include <chrono>
#include <omp.h>
#include "InitializeAdamData.h"

const int TotalModel::NUM_SHAPE_COEFFICIENTS;
const int TotalModel::NUM_VERTICES;
const int TotalModel::NUM_JOINTS;
const int TotalModel::NUM_POSE_PARAMETERS;
const int TotalModel::NUM_FACES;
const int TotalModel::NUM_EXP_BASIS_COEFFICIENTS;

// extern const double U_exp_data[];
extern const double blendW_data[];

template<typename Derived, int rows, int cols>
void initMatrix(Eigen::Matrix<Derived, rows, cols>& m, const Json::Value& value)
{
    if(m.cols() == 1) { // a vector
        m.resize(value.size(), 1);
        auto* m_data = m.data();
        if (strcmp(typeid(Derived).name(), "i") == 0) // the passed in matrix is Int
		    for (uint i = 0; i < value.size(); i++)
	            m_data[i] = value[i].asInt();
        else // the passed in matrix should be double
		    for (uint i = 0; i < value.size(); i++)
                m_data[i] = value[i].asDouble();
    }
    else  { // a matrix (column major)
    	const int nrow = value.size(), ncol = value[0u].size();
        m.resize(nrow, ncol);
        auto* m_data = m.data();
        if (strcmp(typeid(Derived).name(), "i") == 0)
	        for (uint i = 0; i < value.size(); i++)
	            for (uint j = 0; j < value[i].size(); j++)
	            	m_data[j * nrow + i] = value[i][j].asInt();
        else
	        for (uint i = 0; i < value.size(); i++)
	            for (uint j = 0; j < value[i].size(); j++)
                    m_data[j * nrow + i] = value[i][j].asDouble();
    }
    std::cout << "rows " << m.rows() << " cols " << m.cols() << std::endl;
}

template<typename Derived, int rows, int cols, int option>
void initRowMajorMatrix(Eigen::Matrix<Derived, rows, cols, option>& m, const Json::Value& value)
{
    if(m.cols() == 1) { // a vector
        m.resize(value.size(), 1);
        auto* m_data = m.data();
        if (strcmp(typeid(Derived).name(), "i") == 0) // the passed in matrix is Int
		    for (uint i = 0; i < value.size(); i++)
	            m_data[i] = value[i].asInt();
        else // the passed in matrix should be double
		    for (uint i = 0; i < value.size(); i++)
                m_data[i] = value[i].asDouble();
    }
    else  { // a matrix (column major)
    	const int nrow = value.size(), ncol = value[0u].size();
        m.resize(nrow, ncol);
        auto* m_data = m.data();
        if (strcmp(typeid(Derived).name(), "i") == 0)
	        for (uint i = 0; i < value.size(); i++)
	            for (uint j = 0; j < value[i].size(); j++)
	            	m_data[i * ncol + j] = value[i][j].asInt();
        else
	        for (uint i = 0; i < value.size(); i++)
	            for (uint j = 0; j < value[i].size(); j++)
                    m_data[i * ncol + j] = value[i][j].asDouble();
    }
    std::cout << "rows " << m.rows() << " cols " << m.cols() << std::endl;
}

template<typename Derived, int option>
void initSparseMatrix(Eigen::SparseMatrix<Derived, option>& m, const Json::Value& value)
{
	if (strcmp(typeid(Derived).name(), "i") == 0)
	{
		// The first row specifies the size of the sparse matrix
		m.resize(value[0u][0u].asInt(), value[0u][1u].asInt());
		for (uint k = 1u; k < value.size(); k++)
		{
			assert(value[k].size() == 3);
			// From the second row on, triplet correspond to matrix entries
			const int i = value[k][0u].asInt();
			const int j = value[k][1u].asInt();
			m.insert(i, j) = value[k][2u].asInt();
		}
	}
	else
	{
		// The first row specifies the size of the sparse matrix
		m.resize(value[0u][0u].asInt(), value[0u][1u].asInt());
		for (uint k = 1u; k < value.size(); k++)
		{
			assert(value[k].size() == 3);
			// From the second row on, triplet correspond to matrix entries
			const int i = value[k][0u].asInt();
			const int j = value[k][1u].asInt();
			m.insert(i, j) = value[k][2u].asDouble();
		}
	}
	std::cout << "rows " << m.rows() << " cols " << m.cols() << std::endl;
}

void LoadTotalDataFromJson(TotalModel &totalm, const std::string &path, const std::string &pca_path, const std::string &correspondence_path)
{
	printf("Loading from: %s\n", path.c_str());
	Json::Value root, pca_root;
	std::ifstream file;
	file.open(path.c_str(), std::ifstream::in);
    file >> root;

    // Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> stmp;
    initSparseMatrix(totalm.m_J_reg, root["adam_J_regressor_big"]);
    initSparseMatrix(totalm.m_J_reg_smc, root["adam_J_regressor_big_smc"]);
    Eigen::SparseMatrix<double> coco_reg;
    initSparseMatrix(coco_reg, root["small_coco_reg"]);
    totalm.m_small_coco_reg.resize(coco_reg.rows() + 1, coco_reg.cols());
    for (int c = 0; c < coco_reg.outerSize(); c++)
    {
    	for (Eigen::SparseMatrix<double>::InnerIterator it(coco_reg, c); it; ++it)
    	{
    		const int r = it.row();
    		totalm.m_small_coco_reg.insert(r, c) = it.value();
    		if (r == 2 || r == 3)
    			totalm.m_small_coco_reg.insert(coco_reg.rows(), c) = 0.25 * it.value();
    		else if (r == 12)
    			totalm.m_small_coco_reg.insert(coco_reg.rows(), c) = 0.5 * it.value();
    	}
    }
    totalm.m_small_coco_reg.makeCompressed();  // add chest to it

    // initMatrix(totalm.m_blendW, root["blendW"]);
    totalm.m_blendW.resize(18540, 62);
    std::copy(blendW_data, blendW_data + 18540 * 62, totalm.m_blendW.data());
    initMatrix(totalm.m_kintree_table, root["kintree_table"]);
	for (int idt = 0; idt < totalm.m_kintree_table.cols(); idt++) {
		totalm.m_id_to_col[totalm.m_kintree_table(1, idt)] = idt;
	}
	for (int idt = 1; idt < totalm.m_kintree_table.cols(); idt++) {
		totalm.m_parent[idt] = totalm.m_id_to_col[totalm.m_kintree_table(0, idt)];
	}

	initMatrix(totalm.m_correspond_adam2face70_face70Idx, root["correspond_adam2face70_face70Idx"]);
	initMatrix(totalm.m_correspond_adam2face70_adamIdx, root["correspond_adam2face70_adamIdx"]);
	initMatrix(totalm.m_correspond_adam2cocoear_cocobodyIdx, root["correspond_adam2cocoear_cocobodyIdx"]);
	initMatrix(totalm.m_correspond_adam2cocoear_adamIdx, root["correspond_adam2cocoear_adamIdx"]);
	initMatrix(totalm.m_correspond_adam2lHand_adamIdx, root["correspond_adam2lHand_adamIdx"]);
	initMatrix(totalm.m_correspond_adam2lHand_lHandIdx, root["correspond_adam2lHand_lHandIdx"]);
	initMatrix(totalm.m_correspond_adam2rHand_adamIdx, root["correspond_adam2rHand_adamIdx"]);
	initMatrix(totalm.m_correspond_adam2rHand_rHandIdx, root["correspond_adam2rHand_rHandIdx"]);

	totalm.m_indices_jointConst_adamIdx = Eigen::Matrix<int, Eigen::Dynamic, 1>(13, 1);
	totalm.m_indices_jointConst_smcIdx = Eigen::Matrix<int, Eigen::Dynamic, 1>(13, 1);
	totalm.m_indices_jointConst_adamIdx << 16, 18, 20, 1, 4, 7, 17, 19, 21, 2, 5, 8, 12;		
	totalm.m_indices_jointConst_smcIdx << 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0;		
	totalm.face_prior_A_exp.resize(TotalModel::NUM_EXP_BASIS_COEFFICIENTS);
	totalm.face_prior_A_exp << 1.0000,    1.3884,    1.4322,    3.2194,    4.0273,    4.5258,    4.9396,    5.1066,    5.6521,    5.8661,    6.6474,    7.5848,    7.8018,    7.9318,    8.4214,    9.0600,    9.3434,   10.5993,   10.6766,   11.0619,   11.3347,   12.8620,   14.4040,   15.4403,   15.9183,   16.8945,   17.1970,   18.0435,   18.8597,   19.4450,   19.8396,   20.3699,   20.6630,   21.8482,   23.2284,   23.5336,   24.1947,   25.7601,   26.5978,   27.8819,   29.3783,   29.6195,   30.9762,   31.9264,   32.8898,   34.0769,   34.6534,   35.5318,   37.0082,   38.3323,   38.7301,   39.6270,   43.3004,   45.4749,   47.4281,   49.3030,   49.9038,   51.4549,   52.1341,   53.1723,   53.6358,   54.2716,   55.6179,   56.4990,   57.4234,   58.0243,   59.3404,   60.8487,   62.4063,   62.6375,   64.4185,   65.4798,   66.1404,   67.0013,   67.4438,   68.8301,   70.4146,   70.9421,   72.7690,   74.5522,   76.4981,   77.6108,   79.6063,   79.9627,   81.4692,   82.0128,   82.2424,   84.3532,   86.8927,   87.9610,   88.0665,   89.4892,   90.5118,   90.9908,   92.7930,   94.3903,   95.7852,   96.7678,   97.3032,   99.8454,  100.4756,  101.5921,  102.1015,  103.8437,  105.1683,  105.4616,  107.7326,  109.0088,  109.1023,  111.6924,  113.5024,  115.0624,  116.4892,  117.5802,  119.9704,  120.8436,  122.6132,  123.3027,  125.0063,  125.4102,  126.2347,  126.3537,  129.1989,  129.5823,  130.2158,  131.5268,  133.4373,  135.1778,  137.9440,  140.7205,  141.5721,  142.4590,  143.7006,  144.8883,  146.3983,  147.1215,  147.8103,  149.5836,  150.6851,  150.6961,  153.1289,  154.3134,  155.3207,  156.5810,  157.8858,  158.8535,  160.9939,  161.8322,  163.7226,  165.7372,  166.1939,  168.1920,  168.5944,  168.9809,  170.9044,  172.3045,  172.7526,  176.3592,  177.1201,  177.2328,  179.7210,  180.7331,  180.9280,  183.4400,  183.7548,  184.5876,  185.7965,  187.5969,  189.1555,  190.4965,  192.2034,  193.3294,  195.0099,  198.5997,  200.0230,  200.7327,  202.6141,  205.1104,  206.0522,  207.0078,  207.6073,  209.0094,  211.3078,  212.3590,  214.3154,  215.2212,  215.9995,  218.3660,  220.2393,  221.0927,  222.2768,  224.2556,  225.6657,  228.3417,  228.9960,  232.4002,  232.4943,  234.7318,  235.8495,  236.6455;
	// const Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > U_exp_(U_exp_data, 34530, 200);
	Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> U_exp_(34530, 200);
	U_exp_.setZero();  // facewarehouse


	// initRowMajorMatrix(U_exp_, root["U_exp"]);
	initMatrix(totalm.smpl_pose_prior_A, root["pose_prior_A"]);
	initMatrix(totalm.smpl_pose_prior_mu, root["pose_prior_mu"]);
	// hand pose prior
	totalm.hand_pose_prior_mu.resize(60);
	totalm.hand_pose_prior_mu << 
		-0.31050181,  0.37864046,  0.29766361, -0.51211324, -0.37328161,  0.18318686,
		 0.20059148,  0.12364501, -0.30159756,  0.        ,  0.        ,  0.,
		-0.61152409, -0.04833768, -0.19061112,  0.05928512, -0.5397934 , -0.48885571,
		 0.34281583, -0.01293657, -0.17094982,  0.        ,  0.        ,  0.,
		 0.22272256,  0.04743478, -0.16635764, -0.16526452,  0.08733805, -0.59917482,
		-0.04534877, -0.19256482, -0.30474567,  0.        ,  0.        ,  0.,
		 0.13491524, -0.02565558, -0.29364593,  0.10630916,  0.02484566, -0.45862706,
		 0.04190443, -0.14918389, -0.19762223,  0.        ,  0.        ,  0.,
		 0.45947119,  0.05889709, -0.33778687, -0.06110835, -0.11493019, -0.34204716,
		 0.13571404, -0.00922789, -0.18625878,  0.        ,  0.        ,  0.;
	totalm.hand_pose_prior_A.resize(60, 60);
	double A_data[3600] = {
		4.6237e+00, 2.8533e+00, -2.9345e+00, 3.8292e-01, -5.9932e-01, -1.1339e+00, -6.9088e-02, 7.6737e-02, -1.7636e-01, -5.0135e-17, 1.4845e-14, -8.5308e-15, -1.4316e+00, -3.0481e-01, -4.2580e-02, 1.0423e+00, -5.6255e-02, 1.7218e-02, 3.9209e-01, -2.1005e-01, 3.4124e-01, -1.8729e-15, 1.3012e-17, -4.5572e-16, 1.0959e+00, -6.2672e-02, 6.2878e-02, -3.2745e-01, -2.2233e-01, -5.4267e-02, 2.3478e-01, 6.0584e-02, -1.5185e-02, -1.5747e-16, 1.7588e-17, 1.3458e-18, 6.2324e-01, 1.4295e-01, 3.3783e-01, -4.5662e-01, -2.2564e-02, -7.1402e-02, -1.8969e-02, 3.9372e-02, 3.3418e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.0825e+00, 2.5102e-01, 6.3424e-02, -2.3049e-01, -1.2833e-02, 2.5149e-01, 3.3548e-02, 2.8449e-02, -4.4981e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.8533e+00, 1.0955e+01, -3.6314e+00, 2.2093e+00, 4.0686e-01, -3.4842e+00, -3.5782e-01, 1.2989e+00, -2.3560e-01, 2.6279e-15, 2.8418e-14, -1.2643e-14, -1.6099e-01, -2.3849e-01, -5.7372e-02, 9.3251e-01, 4.8888e-01, -4.3449e-02, -5.4222e-02, -4.7873e-01, 1.6766e-01, -2.7824e-15, 1.3705e-15, 1.2047e-17, 2.5764e-01, -3.9161e-01, 1.6503e-02, 3.5185e-01, 2.5093e-01, -1.1469e-03, -2.6458e-01, 4.3736e-04, 1.3783e-02, 1.2420e-16, -8.4643e-16, -4.0874e-16, -7.3559e-01, 7.6978e-01, 1.0798e-01, -3.2488e-02, -2.3679e-01, -6.0452e-02, -2.2232e-01, 2.6429e-01, -2.0660e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -9.8582e-01, 6.8863e-01, -8.9873e-01, 2.0994e-01, -9.2535e-01, 3.6545e-01, 7.4480e-02, -2.3556e-01, 8.4561e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.9345e+00, -3.6314e+00, 1.4875e+01, -1.3555e+00, -1.3129e+00, 1.2073e+00, -2.0953e+00, -1.0944e+00, 1.1333e+00, 5.0799e-15, -2.3335e-14, 2.5327e-14, -8.3509e-01, -5.8216e-01, -5.2668e-01, 4.5568e-02, 2.6612e-01, -4.0549e-01, 7.4775e-02, 1.2095e-01, 1.1494e-01, 1.4609e-15, -3.7009e-15, 1.0481e-15, 3.7444e-01, -2.4216e-01, 1.3318e-01, -2.8090e-02, -2.3585e-01, -7.3101e-02, -1.0152e-01, 6.3199e-02, 9.6651e-02, 2.9804e-16, -2.8683e-15, 2.6279e-17, -6.9731e-01, 8.3519e-01, -2.6741e-01, 2.9372e-01, 3.7231e-02, 4.6564e-02, -8.8317e-02, 4.7269e-02, 1.5216e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -6.3693e-01, -7.5272e-01, 1.9845e-02, 2.9858e-01, 1.5179e-01, 1.6827e-01, 1.5837e-01, -2.6857e-02, 2.0729e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.8292e-01, 2.2093e+00, -1.3555e+00, 6.4032e+00, 2.0773e+00, -2.4078e+00, 2.0401e-01, 1.6191e-01, -4.8229e-01, 1.4400e-15, 1.3311e-14, -4.4120e-15, -7.9299e-01, -2.0948e-01, -7.0115e-02, 6.9153e-01, -2.3171e-02, -3.6757e-02, 2.3616e-01, 2.4008e-01, -5.2847e-02, -2.8305e-15, 7.6127e-16, -9.1292e-16, 7.1746e-01, -5.1141e-01, 1.7924e-01, 6.8694e-01, 3.7936e-01, 5.1279e-04, -2.8141e-01, -1.0271e-01, 7.8002e-02, 1.2077e-16, -9.6029e-16, 3.1221e-17, -6.2096e-01, -1.6529e-01, 5.3400e-02, -1.0036e-01, 1.0556e-01, -2.4823e-02, -7.2247e-02, -8.6600e-03, -1.8417e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.5250e-01, 9.8348e-02, 2.5492e-01, 3.4457e-02, -2.7773e-01, 5.0920e-02, -1.6759e-01, 1.1129e-01, -3.0032e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-5.9932e-01, 4.0686e-01, -1.3129e+00, 2.0773e+00, 6.0555e+00, -1.6095e-01, 6.0316e-01, 1.1293e+00, 3.1559e-01, 1.8814e-15, 5.7255e-15, -8.7567e-16, -2.4504e-01, -2.9637e-01, -6.2052e-01, 4.9536e-01, -3.9026e-01, 2.7353e-01, 4.6178e-02, 5.7149e-01, -2.9352e-01, -2.0230e-15, 8.0305e-16, -4.9834e-16, 7.7903e-01, 1.8184e-01, 1.1225e-01, 3.1651e-01, 2.6607e-01, 6.9210e-02, -2.2603e-01, 4.1504e-02, 2.1731e-02, 4.3457e-16, -4.0821e-16, -1.8657e-16, -3.7786e-01, -1.3590e-01, -1.2468e-01, 5.5071e-01, 2.6957e-01, 9.3515e-02, -4.7147e-02, 1.2984e-01, -7.5386e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00, 4.3842e-01, 1.8552e-01, 3.9540e-01, -1.9184e-01, 7.6035e-02, -1.1177e-01, -8.9059e-02, 6.2909e-02, -1.6047e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.1339e+00, -3.4842e+00, 1.2073e+00, -2.4078e+00, -1.6095e-01, 7.9617e+00, -7.4828e-01, 3.3599e-01, 5.1624e-01, -8.6246e-16, -1.7518e-14, 9.4678e-15, 1.1675e+00, 9.4841e-02, -3.9291e-01, -7.1258e-01, 1.0413e-01, 1.4086e-01, -1.9987e-01, 3.7789e-01, -3.7469e-01, 1.9503e-15, 2.3695e-16, 6.7360e-16, -8.6743e-02, 4.8230e-01, 2.2649e-01, -7.5120e-01, -5.0363e-01, 6.5049e-02, 2.9549e-01, 7.4797e-02, -3.1953e-02, 2.0995e-16, 7.9786e-16, -4.9194e-16, -2.6182e-02, 7.1631e-02, 1.2445e-01, 3.3496e-01, -1.5947e-01, 3.7192e-02, 8.1245e-02, -6.7999e-02, -1.9903e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -3.1872e-01, 7.1171e-01, -1.3393e-01, 1.6769e-01, 4.3783e-01, -6.3743e-02, 1.2318e-01, 1.0087e-01, 1.9219e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-6.9088e-02, -3.5782e-01, -2.0953e+00, 2.0401e-01, 6.0316e-01, -7.4828e-01, 7.1293e+00, 3.2208e+00, -2.3471e+00, -1.7838e-16, -2.3360e-15, 1.0554e-15, 1.3866e+00, 1.8490e-01, -5.7886e-02, -9.8070e-01, -4.2587e-01, 4.4943e-02, -1.5305e-01, -8.5646e-02, -1.6544e-01, 5.7003e-16, 7.3418e-16, -2.9460e-17, -6.8787e-02, -3.1524e-01, -6.6041e-02, -8.0599e-01, -1.0090e+00, 3.8768e-02, 5.5392e-01, -6.9564e-02, 5.8166e-02, 1.8979e-16, 1.1386e-15, 4.7049e-16, 7.1648e-01, 1.5819e-02, 2.7001e-01, 1.6070e-01, 1.6471e-01, 1.2836e-02, -1.3340e-03, -1.8850e-01, 5.0730e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.4450e-01, 1.1300e-01, -5.8287e-02, 1.3319e-01, 2.1445e-01, -4.6623e-02, 1.1143e-01, 9.7190e-02, -7.1268e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		7.6737e-02, 1.2989e+00, -1.0944e+00, 1.6191e-01, 1.1293e+00, 3.3599e-01, 3.2208e+00, 9.6362e+00, 2.3660e+00, 7.5717e-15, 3.9790e-15, 3.7113e-15, 4.2962e-01, -4.1240e-01, -2.1087e-01, -8.5727e-01, 1.9088e-01, -1.3092e-01, 1.3128e-01, 1.1000e-03, 2.0751e-01, -1.3988e-15, 8.9749e-16, 6.4119e-16, 1.1446e-01, -5.5401e-01, -4.6221e-02, -4.9256e-01, -2.7214e-01, 4.1423e-02, 1.6038e-01, 4.6101e-02, 1.0656e-02, 6.1992e-16, -1.2021e-15, -8.7037e-17, -1.9262e-01, 1.3992e-01, -3.9160e-01, 1.1877e-01, 1.5222e-01, 7.0006e-02, -1.1432e-01, -5.2929e-03, 1.0069e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 7.2625e-02, -3.1756e-01, -1.2837e-01, 1.2791e-02, -1.3546e-01, 2.4428e-01, -2.3274e-02, 2.3567e-01, -2.3458e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.7636e-01, -2.3560e-01, 1.1333e+00, -4.8229e-01, 3.1559e-01, 5.1624e-01, -2.3471e+00, 2.3660e+00, 7.1192e+00, 5.7152e-15, 2.9154e-15, 2.4597e-15, -1.0717e+00, -2.9171e-01, -1.4148e-01, 3.9189e-01, 2.6433e-01, -3.1425e-01, 3.4728e-01, -3.6664e-02, 1.5375e-01, -1.6684e-15, -1.8011e-16, 3.9711e-16, 5.1292e-01, 8.4716e-02, 2.0221e-01, 4.7529e-01, 8.5896e-01, -2.5167e-02, -3.7771e-01, 6.9097e-02, -9.1170e-02, 2.9900e-16, -1.9355e-15, -4.4227e-16, -7.0246e-01, 1.8886e-01, -3.4700e-01, -7.0114e-02, -1.4498e-02, -2.7268e-03, -3.6117e-02, 1.5452e-01, -1.0385e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 5.5617e-01, -1.8537e-01, 3.2121e-01, -2.4834e-01, -5.0368e-01, 4.6939e-02, -1.1917e-01, -1.1377e-01, -2.7920e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-9.4488e-16, -6.6638e-15, 1.0284e-14, -7.0928e-16, 1.2164e-15, 5.7787e-15, -7.0336e-15, -4.7997e-15, 4.8407e-15, 4.8587e-29, -5.9598e-30, 1.5407e-28, -1.2481e-14, 1.2390e-14, -2.0156e-14, -7.0992e-15, 6.7531e-15, -1.4933e-15, -1.5712e-14, 1.5614e-14, -1.5403e-14, -4.3025e-29, 1.0217e-29, -9.5095e-30, 4.4081e-14, -2.8225e-14, 2.3461e-14, 1.6414e-15, -6.2212e-15, 1.0654e-16, 2.5665e-15, -1.1785e-15, 2.4478e-16, 3.0755e-30, -3.8681e-29, -1.0908e-29, -3.1277e-14, 1.5575e-14, -1.6929e-14, -9.7501e-15, -1.3747e-15, -1.6090e-15, 4.7656e-16, -9.8925e-16, 3.4571e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.8263e-14, -1.8499e-15, 9.2851e-15, 4.7284e-15, -3.1288e-15, 3.9168e-15, 2.5415e-15, -2.3713e-15, 1.8392e-15, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.6424e-15, -7.7505e-15, 2.0893e-14, -4.4119e-15, -5.8298e-15, 5.4250e-15, -1.0111e-14, -5.9630e-15, 7.2013e-15, 5.0732e-29, -8.3558e-30, 1.1838e-28, -8.8255e-15, 1.5867e-15, -7.8027e-15, -1.1945e-15, 1.2904e-15, -8.6903e-16, 6.5556e-17, 3.2044e-15, -2.0907e-15, -2.9145e-29, 1.0116e-31, -7.1274e-30, 3.6640e-14, -1.0749e-14, 1.3622e-14, 4.9826e-15, -9.5351e-15, 5.9927e-16, 1.5867e-15, -2.7626e-15, 1.9950e-15, 2.1637e-30, -2.1369e-29, -6.9196e-30, -2.0662e-14, 6.1087e-15, -5.8337e-15, -2.3237e-14, -2.9501e-15, -5.1744e-15, 3.9576e-16, -1.3484e-17, -7.7247e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.0508e-15, 3.6770e-16, -1.7709e-15, 4.5817e-15, 3.5457e-15, 2.0263e-15, 1.6000e-15, -1.0679e-15, 6.3192e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.6896e-16, 8.5523e-17, 2.5979e-16, 6.1349e-16, 1.3324e-15, 1.2561e-15, -1.7436e-15, -1.0574e-16, 2.4934e-15, 1.5437e-30, -5.0318e-30, 1.0067e-29, 6.4895e-15, -7.3457e-15, 1.8341e-15, -2.0487e-15, -2.7934e-15, 3.9042e-16, 9.0738e-15, -7.6799e-15, 8.5965e-15, -2.4564e-30, 1.7063e-30, -9.7125e-30, 3.6481e-15, 1.1098e-14, 9.2395e-16, -2.2879e-15, 5.3633e-15, 1.7730e-16, 2.1643e-15, 3.2212e-16, 3.9605e-16, 4.8018e-30, 1.2463e-30, -3.3117e-30, -1.6266e-14, 3.0967e-15, -8.1856e-15, -1.4324e-14, -9.1305e-16, -3.9342e-15, -3.1568e-15, 1.7678e-15, -2.3123e-15, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.9611e-14, 7.1362e-16, 1.1299e-14, 4.7103e-15, -5.0686e-15, 3.6809e-15, 1.9333e-15, -1.7806e-16, 1.4728e-15, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.4316e+00, -1.6099e-01, -8.3509e-01, -7.9299e-01, -2.4504e-01, 1.1675e+00, 1.3866e+00, 4.2962e-01, -1.0717e+00, -1.4455e-14, -2.6382e-14, -1.2228e-15, 1.3260e+01, -9.9967e-01, -5.0728e-01, 2.0574e+00, -1.3746e+00, 8.3792e-01, 7.6364e-02, 7.5719e-01, -3.9343e-01, 7.9056e-15, 2.4761e-15, 1.1728e-15, -3.4201e+00, 9.1885e-01, 4.8418e-01, 1.0214e+00, 1.3373e+00, -5.8191e-02, -1.0154e+00, -2.1559e-02, -2.7000e-02, 2.5600e-15, 4.8138e-15, -1.0947e-15, 1.1889e+00, 4.2514e-01, 1.9283e-01, -6.5668e-01, 4.6277e-01, -1.6960e-01, -3.1009e-01, 2.0779e-02, 7.8953e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00, 9.2012e-01, 6.8247e-01, -2.3349e-01, 4.9035e-02, -1.7378e-01, 2.1765e-01, 3.8838e-02, -1.1186e-01, -8.4742e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-3.0481e-01, -2.3849e-01, -5.8216e-01, -2.0948e-01, -2.9637e-01, 9.4841e-02, 1.8490e-01, -4.1240e-01, -2.9171e-01, 5.4393e-15, -4.8827e-15, 3.1214e-15, -9.9967e-01, 8.2619e+00, -1.4239e+00, -2.2508e-01, 5.3105e-01, 1.7674e-01, -5.9587e-02, 3.4564e-01, -1.0177e-01, -8.4606e-17, 2.3032e-16, 1.3777e-15, 3.3183e-02, -3.2117e+00, 2.8676e-01, 2.2788e-01, 1.1519e-01, -7.5589e-02, 3.5779e-01, 7.2770e-02, -7.8576e-02, -8.3256e-16, -1.4955e-15, 3.7775e-16, 6.3387e-02, 4.0771e-02, -2.4326e-01, 2.7624e-01, -3.4437e-01, 1.4033e-01, 2.5641e-02, 7.8790e-03, 5.1422e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -2.3105e-01, 8.6926e-01, -5.2970e-01, 5.1637e-01, -7.4942e-01, 1.7798e-01, 3.4297e-02, -3.4108e-02, 2.9605e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-4.2580e-02, -5.7372e-02, -5.2668e-01, -7.0115e-02, -6.2052e-01, -3.9291e-01, -5.7886e-02, -2.1087e-01, -1.4148e-01, -3.4972e-15, 2.3428e-15, -9.7884e-15, -5.0728e-01, -1.4239e+00, 5.5180e+00, -1.6163e-02, -1.0106e+00, -5.8153e-01, 1.1186e+00, -4.3530e-01, 1.1436e+00, 1.6762e-15, -3.3171e-16, -6.7370e-16, -2.6028e+00, 1.3034e+00, -2.9972e+00, 6.3631e-02, -2.9907e-01, 1.1333e-01, 1.6474e-01, 1.4194e-02, 1.1432e-01, -1.5328e-16, 2.2632e-15, 8.2948e-16, 5.6060e-01, -2.3754e-01, 2.0730e-01, -5.6315e-02, 1.3868e-01, -1.1704e-02, -4.4974e-02, 2.8664e-02, -1.4352e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -5.4843e-01, -4.1430e-01, 3.0828e-02, -1.1308e-01, -1.4442e-01, 1.0971e-01, -7.5438e-02, 2.6668e-02, -1.0387e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.0423e+00, 9.3251e-01, 4.5568e-02, 6.9153e-01, 4.9536e-01, -7.1258e-01, -9.8070e-01, -8.5727e-01, 3.9189e-01, -9.9764e-15, -2.8646e-15, -5.2342e-15, 2.0574e+00, -2.2508e-01, -1.6163e-02, 1.5132e+01, 1.0769e+00, -6.1512e-02, -3.7575e-01, 3.3744e-01, -1.3055e-01, 6.3562e-15, -1.0663e-15, 1.0893e-15, -2.1063e+00, 4.5443e-01, 1.2473e-01, -1.6091e+00, -1.3329e+00, 4.3436e-03, 2.6925e-01, 1.0904e-01, -6.9467e-02, 4.1758e-15, 1.3232e-15, -2.2649e-15, 3.4469e-01, -9.5260e-02, -5.8761e-01, -1.0351e+00, -1.5724e-01, -2.4734e-01, 1.3070e-01, -2.1136e-01, 1.0133e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -3.5175e-01, 3.8380e-01, -1.4068e-01, 5.0227e-01, 1.0222e+00, -7.4709e-02, -7.9123e-03, 1.0704e-01, -1.6751e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-5.6255e-02, 4.8888e-01, 2.6612e-01, -2.3171e-02, -3.9026e-01, 1.0413e-01, -4.2587e-01, 1.9088e-01, 2.6433e-01, 2.2628e-15, 5.6852e-15, 2.1418e-15, -1.3746e+00, 5.3105e-01, -1.0106e+00, 1.0769e+00, 7.4235e+00, -3.5917e+00, 8.3040e-01, 1.5507e-01, 5.1970e-01, -1.3937e-15, -1.0600e-15, -9.6341e-16, -5.0775e-01, -3.7139e-01, 8.3478e-01, 7.7855e-01, -1.4957e+00, 7.0937e-02, -2.5042e-01, -1.8782e-01, -2.7207e-02, 3.7934e-16, -3.2019e-15, -7.6431e-16, 8.0855e-02, -1.0068e-01, -3.3021e-01, 3.5930e-02, -1.0056e-01, 3.6680e-02, 1.7583e-01, -1.4079e-01, 6.6551e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 9.9470e-02, 5.2037e-02, 3.5280e-01, -2.1074e-02, 3.1345e-01, -1.0511e-01, 1.0601e-01, -3.7604e-02, 3.0089e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.7218e-02, -4.3449e-02, -4.0549e-01, -3.6757e-02, 2.7353e-01, 1.4086e-01, 4.4943e-02, -1.3092e-01, -3.1425e-01, -8.2010e-16, -4.4631e-15, -1.8315e-15, 8.3792e-01, 1.7674e-01, -5.8153e-01, -6.1512e-02, -3.5917e+00, 5.2252e+00, -1.3346e+00, -7.5237e-01, -9.2228e-01, 1.2327e-15, 3.9847e-16, 1.2057e-15, 5.2321e-01, -7.4990e-03, -5.5748e-01, -3.6237e-01, 9.9715e-01, -2.5876e-01, 3.1361e-01, 1.9321e-01, -1.7200e-01, -1.8622e-16, 2.1443e-15, 4.1244e-16, -2.0943e-01, -1.1635e-01, 2.8824e-01, 3.5090e-01, -1.9996e-01, -5.2526e-02, -5.3191e-02, 1.5338e-01, -2.1692e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.7828e-01, 7.1747e-02, -3.6910e-01, 2.7339e-01, -2.3771e-01, -1.7238e-02, 1.4897e-02, -8.2564e-02, -4.5474e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.9209e-01, -5.4222e-02, 7.4775e-02, 2.3616e-01, 4.6178e-02, -1.9987e-01, -1.5305e-01, 1.3128e-01, 3.4728e-01, 4.2996e-15, 2.2937e-15, -1.4125e-15, 7.6364e-02, -5.9587e-02, 1.1186e+00, -3.7575e-01, 8.3040e-01, -1.3346e+00, 9.0366e+00, -4.8436e-01, 3.2341e+00, -8.4662e-16, -2.9863e-16, -1.7417e-15, -2.6746e-01, 9.4851e-01, -6.1829e-01, -1.9377e-01, -1.5254e-01, -1.1685e-01, -1.2110e-02, 2.3164e-01, -7.7302e-02, -1.3358e-17, 2.4957e-16, 2.8377e-16, 2.7842e-01, 3.3197e-01, 5.1299e-02, -8.1504e-01, -8.8143e-02, -3.5130e-01, 1.0986e-01, -2.2517e-02, -9.1791e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 6.3850e-01, 7.4928e-02, 3.5394e-01, 1.1379e-01, -3.3512e-01, 1.2347e-02, 1.3641e-01, 1.0044e-01, 4.4947e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.1005e-01, -4.7873e-01, 1.2095e-01, 2.4008e-01, 5.7149e-01, 3.7789e-01, -8.5646e-02, 1.1000e-03, -3.6664e-02, -1.2010e-14, -3.7411e-15, 1.1994e-14, 7.5719e-01, 3.4564e-01, -4.3530e-01, 3.3744e-01, 1.5507e-01, -7.5237e-01, -4.8436e-01, 1.0284e+01, -4.4706e+00, -1.6241e-15, 4.0174e-15, 1.0368e-16, 4.1772e-01, 2.4089e-01, 3.5516e-01, 2.2270e-01, -1.6738e-01, 7.6709e-03, 9.8802e-02, -3.0788e-01, 9.6542e-03, 3.7372e-16, -1.5768e-15, -1.4317e-15, -3.8642e-01, -5.0669e-01, -1.3979e-01, 4.1766e-01, -1.4748e-01, 1.1460e-01, 1.0204e-01, -7.7122e-02, 1.1976e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.0969e-01, 3.1381e-01, -4.3079e-01, -1.7280e-02, 3.8621e-02, 5.0524e-02, -8.3200e-02, -3.2512e-02, -8.6581e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.4124e-01, 1.6766e-01, 1.1494e-01, -5.2847e-02, -2.9352e-01, -3.7469e-01, -1.6544e-01, 2.0751e-01, 1.5375e-01, 8.4481e-15, 3.6839e-15, -7.2978e-15, -3.9343e-01, -1.0177e-01, 1.1436e+00, -1.3055e-01, 5.1970e-01, -9.2228e-01, 3.2341e+00, -4.4706e+00, 6.5393e+00, 5.6878e-16, -2.2425e-15, -9.9742e-16, -4.3939e-01, 3.8251e-01, -3.8354e-01, -2.1733e-01, 6.2630e-02, -1.3600e-01, 1.5827e-01, 1.8271e-01, -3.3914e-01, -1.2788e-16, 7.9756e-16, 8.3831e-16, 3.0457e-01, 4.8914e-01, 5.1900e-02, -6.1237e-01, 1.8732e-02, -3.0075e-01, 1.2812e-01, -8.0219e-03, -1.1652e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 4.3333e-01, -8.1699e-02, 2.8971e-01, 5.2140e-02, -3.4783e-01, 1.7593e-02, 2.2170e-01, -1.0607e-02, 1.0504e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.2131e-16, 1.7494e-15, -5.2009e-15, 6.5151e-16, 1.2760e-15, 2.8214e-16, 3.2640e-15, 3.6229e-15, -7.9495e-16, -4.1887e-30, 5.2562e-30, 4.6318e-30, 2.4288e-15, -1.1125e-16, -8.7952e-16, -3.5069e-15, 2.6878e-17, -3.3234e-16, -1.5913e-15, 4.9657e-15, -3.5177e-15, -2.8296e-30, 4.5977e-30, 2.4208e-31, 8.1678e-16, -1.0396e-16, 1.9162e-15, 2.2595e-15, -1.8153e-15, 2.2630e-16, 3.5046e-16, -6.9792e-16, 5.2314e-16, 1.5452e-32, -4.9351e-31, -1.0028e-30, -7.3223e-16, -2.2838e-15, -7.9532e-16, -1.7744e-15, 5.4837e-16, -3.2459e-16, -2.7952e-16, 1.5014e-16, -7.8668e-17, 0.0000e+00, 0.0000e+00, 0.0000e+00, -8.2994e-16, 1.6057e-15, -1.1781e-15, -7.4175e-16, 1.7274e-16, -3.1045e-16, 1.4549e-17, -4.7325e-16, -4.7010e-17, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.2747e-16, -1.3255e-15, 2.6382e-15, 9.9255e-17, -6.8713e-16, -5.4953e-16, -1.0094e-15, -1.2623e-15, 1.4352e-16, 1.0201e-29, 7.5701e-30, 5.3496e-30, -4.0450e-15, -1.2726e-15, 6.3939e-16, -5.3079e-15, 5.7290e-16, -1.0909e-15, 3.3544e-15, -2.6812e-15, 3.0370e-15, -5.0906e-30, -1.6789e-30, -2.6877e-30, 3.4429e-15, 2.1657e-15, 3.7713e-16, 7.1973e-16, 1.3046e-16, 1.7785e-16, 9.0850e-16, -8.9265e-16, 4.4664e-16, -1.6773e-30, -1.6014e-30, 8.4813e-31, -1.7465e-15, -5.6222e-16, 1.0975e-17, -3.6239e-15, -1.4142e-15, -8.0086e-16, 2.9744e-16, 3.1606e-17, -2.9840e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.5776e-15, -1.4959e-15, 1.2468e-15, 3.9219e-16, -1.9508e-16, 5.2044e-16, 4.9356e-16, -1.2002e-16, 3.0863e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.6801e-16, 5.4765e-16, 8.9334e-17, 4.5633e-16, -1.7843e-16, -1.0845e-15, -1.4099e-15, -2.2038e-15, -2.5604e-16, -3.3237e-30, -1.9884e-30, -1.2463e-29, 1.4542e-15, 6.2249e-16, -1.8118e-16, 2.9692e-15, 1.5641e-15, -8.4082e-16, 1.1802e-15, -2.2691e-15, 1.7635e-15, 3.9642e-30, -2.5400e-30, 1.0294e-30, -4.6667e-15, 6.9634e-16, 4.3653e-16, 2.8523e-15, 1.1149e-15, -1.0327e-16, -1.6039e-15, -3.1623e-16, 2.0714e-16, 4.6285e-31, 1.3560e-30, 2.3563e-31, 2.4797e-15, -1.6048e-15, -2.0168e-16, 1.5285e-15, 9.4869e-16, 3.0894e-16, -5.7740e-16, 5.7747e-16, -3.0270e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, -3.6960e-16, 1.1146e-15, 2.3230e-16, -8.7725e-16, 6.9459e-16, -9.8295e-16, -7.6467e-16, 5.3817e-16, -5.2130e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.0959e+00, 2.5764e-01, 3.7444e-01, 7.1746e-01, 7.7903e-01, -8.6743e-02, -6.8787e-02, 1.1446e-01, 5.1292e-01, 1.4695e-14, 2.0345e-14, 2.4852e-14, -3.4201e+00, 3.3183e-02, -2.6028e+00, -2.1063e+00, -5.0775e-01, 5.2321e-01, -2.6746e-01, 4.1772e-01, -4.3939e-01, -1.3521e-14, 1.8284e-15, -3.0986e-15, 1.7989e+01, -1.9892e+00, 2.9789e+00, -1.7436e+00, -2.0599e+00, 2.1509e-01, 1.6420e+00, 9.6683e-03, 5.2609e-02, -8.8621e-16, -4.8811e-15, -9.4496e-16, -3.3993e+00, 1.5934e+00, 1.1473e+00, -9.9204e-01, -2.5525e-01, -2.3622e-01, 2.5669e-01, -1.4729e-01, 1.3453e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 6.4226e-01, 3.6692e-01, -3.7571e-01, 1.0559e-01, 1.8932e-01, 1.3398e-01, 1.5696e-01, -1.7520e-02, -2.0629e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-6.2672e-02, -3.9161e-01, -2.4216e-01, -5.1141e-01, 1.8184e-01, 4.8230e-01, -3.1524e-01, -5.5401e-01, 8.4716e-02, -1.4663e-14, 3.8571e-15, -1.1578e-14, 9.1885e-01, -3.2117e+00, 1.3034e+00, 4.5443e-01, -3.7139e-01, -7.4990e-03, 9.4851e-01, 2.4089e-01, 3.8251e-01, 2.7986e-15, -5.2835e-16, -9.8748e-16, -1.9892e+00, 1.4039e+01, -1.5580e+00, -4.7428e-01, -2.4969e-02, 3.1584e-01, -1.3301e-01, -1.3713e-01, 3.6514e-01, 3.5608e-16, 5.2314e-15, -3.9704e-16, 1.1641e+00, -3.5855e+00, 1.4651e+00, 2.6323e-01, -3.4190e-02, 5.6294e-02, -1.5586e-01, 2.9272e-02, -4.7531e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 6.0945e-01, -1.0437e-01, 4.8598e-01, 3.8364e-01, -3.3286e-01, 2.5556e-01, 2.5702e-02, 1.2156e-01, 1.8995e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		6.2878e-02, 1.6503e-02, 1.3318e-01, 1.7924e-01, 1.1225e-01, 2.2649e-01, -6.6041e-02, -4.6221e-02, 2.0221e-01, 4.7328e-15, -4.3052e-16, 1.5698e-14, 4.8418e-01, 2.8676e-01, -2.9972e+00, 1.2473e-01, 8.3478e-01, -5.5748e-01, -6.1829e-01, 3.5516e-01, -3.8354e-01, -2.1711e-15, 1.3630e-15, 1.4662e-16, 2.9789e+00, -1.5580e+00, 7.4912e+00, 3.9793e-01, -5.7837e-01, -3.3577e-01, -2.1118e-01, 2.5245e-02, 4.0798e-02, 8.1608e-16, -3.7175e-15, -1.8698e-15, -2.3408e+00, -5.8331e-01, -3.2172e+00, -4.4997e-01, -1.7081e-01, 1.0669e-01, 1.9973e-01, -1.5148e-01, 6.8148e-03, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.5714e-01, 1.0693e-01, -1.8028e-01, 4.4999e-02, 2.5212e-01, 5.8853e-02, 1.1255e-01, -6.0748e-02, -1.9705e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-3.2745e-01, 3.5185e-01, -2.8090e-02, 6.8694e-01, 3.1651e-01, -7.5120e-01, -8.0599e-01, -4.9256e-01, 4.7529e-01, 4.4007e-15, -1.3340e-15, -3.0865e-15, 1.0214e+00, 2.2788e-01, 6.3631e-02, -1.6091e+00, 7.7855e-01, -3.6237e-01, -1.9377e-01, 2.2270e-01, -2.1733e-01, -4.4281e-15, -2.4327e-15, -1.3668e-15, -1.7436e+00, -4.7428e-01, 3.9793e-01, 1.4632e+01, 1.5697e+00, 2.1154e-01, -8.5980e-01, -7.5466e-01, 6.9943e-01, 1.1598e-16, -1.0254e-15, 1.4652e-16, -4.9140e-01, 4.0682e-01, 5.0265e-02, -9.8377e-01, 2.6164e-01, -6.6653e-02, -2.5093e-01, 1.0621e-01, 8.9242e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.9437e-01, -3.9144e-02, -2.8038e-01, -5.8698e-01, 3.2079e-01, -3.9079e-01, -2.4441e-01, -4.1534e-03, -7.2792e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.2233e-01, 2.5093e-01, -2.3585e-01, 3.7936e-01, 2.6607e-01, -5.0363e-01, -1.0090e+00, -2.7214e-01, 8.5896e-01, -2.3480e-15, -4.6747e-15, -7.1532e-15, 1.3373e+00, 1.1519e-01, -2.9907e-01, -1.3329e+00, -1.4957e+00, 9.9715e-01, -1.5254e-01, -1.6738e-01, 6.2630e-02, 1.5636e-15, 2.3687e-16, 5.7246e-16, -2.0599e+00, -2.4969e-02, -5.7837e-01, 1.5697e+00, 1.0282e+01, -3.2700e-01, 4.5405e-01, 6.1589e-01, -7.0055e-01, -1.2405e-15, 1.4019e-15, 9.3143e-16, 1.5947e-01, -7.8567e-02, 7.6522e-01, 4.8362e-01, -7.9666e-01, 7.4942e-02, -1.1737e-01, 8.0865e-02, -1.9617e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 8.0787e-01, -2.3491e-01, 6.8085e-01, 9.5617e-02, -4.3152e-01, 6.3803e-02, -2.8485e-01, 7.9244e-01, -2.1353e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-5.4267e-02, -1.1469e-03, -7.3101e-02, 5.1279e-04, 6.9210e-02, 6.5049e-02, 3.8768e-02, 4.1423e-02, -2.5167e-02, 1.2942e-16, 8.1255e-16, -3.0656e-16, -5.8191e-02, -7.5589e-02, 1.1333e-01, 4.3436e-03, 7.0937e-02, -2.5876e-01, -1.1685e-01, 7.6709e-03, -1.3600e-01, -3.1276e-16, -4.9082e-17, -1.4875e-16, 2.1509e-01, 3.1584e-01, -3.3577e-01, 2.1154e-01, -3.2700e-01, 1.8239e+00, -6.6083e-02, -4.6762e-01, 3.5640e-01, 4.3375e-17, 4.7374e-17, -2.8361e-17, -5.7918e-03, -9.2315e-03, -5.1608e-03, -1.9484e-02, -1.5715e-01, -1.8164e-01, 1.1807e-01, 2.4791e-02, -1.4911e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 3.0233e-03, 1.3572e-01, -1.8688e-01, 1.1803e-02, 1.2187e-01, -1.6197e-01, 5.8441e-02, -1.1494e-01, -2.0086e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.3478e-01, -2.6458e-01, -1.0152e-01, -2.8141e-01, -2.2603e-01, 2.9549e-01, 5.5392e-01, 1.6038e-01, -3.7771e-01, -9.8016e-16, 2.1853e-15, 2.0313e-15, -1.0154e+00, 3.5779e-01, 1.6474e-01, 2.6925e-01, -2.5042e-01, 3.1361e-01, -1.2110e-02, 9.8802e-02, 1.5827e-01, -8.1654e-17, 9.7556e-16, -3.5414e-16, 1.6420e+00, -1.3301e-01, -2.1118e-01, -8.5980e-01, 4.5405e-01, -6.6083e-02, 8.5438e+00, 7.6562e-01, -3.9202e-01, -2.9967e-16, 3.9521e-16, 7.2383e-17, -8.5392e-02, -1.3757e-01, -6.2622e-03, -1.0141e-01, -3.1703e-02, 8.3925e-02, -2.0031e-01, 2.1399e-02, 8.7481e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -2.3420e-01, -2.8572e-01, -1.6440e-01, -2.9129e-01, -2.4468e-01, 9.5912e-02, -9.1327e-02, -9.7836e-02, 4.2317e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		6.0584e-02, 4.3736e-04, 6.3199e-02, -1.0271e-01, 4.1504e-02, 7.4797e-02, -6.9564e-02, 4.6101e-02, 6.9097e-02, -8.2357e-16, -1.6724e-16, -5.3239e-18, -2.1559e-02, 7.2770e-02, 1.4194e-02, 1.0904e-01, -1.8782e-01, 1.9321e-01, 2.3164e-01, -3.0788e-01, 1.8271e-01, 7.6938e-16, 4.5430e-16, 3.9716e-16, 9.6683e-03, -1.3713e-01, 2.5245e-02, -7.5466e-01, 6.1589e-01, -4.6762e-01, 7.6562e-01, 4.8985e+00, -1.3696e+00, -2.0895e-16, 2.1314e-16, 1.2703e-16, 1.8959e-01, 7.7973e-02, 4.2442e-02, 4.2874e-01, -3.2357e-01, 9.8480e-02, -2.3392e-01, -6.7030e-02, 2.3852e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 2.9182e-02, -1.3436e-01, 7.4996e-03, -5.5631e-02, -5.4113e-02, 9.9229e-02, 1.3871e-01, -2.3567e-01, 5.2988e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.5185e-02, 1.3783e-02, 9.6651e-02, 7.8002e-02, 2.1731e-02, -3.1953e-02, 5.8166e-02, 1.0656e-02, -9.1170e-02, 5.4354e-16, 5.9673e-16, 2.2767e-16, -2.7000e-02, -7.8576e-02, 1.1432e-01, -6.9467e-02, -2.7207e-02, -1.7200e-01, -7.7302e-02, 9.6542e-03, -3.3914e-01, -5.5482e-16, -3.4395e-16, -1.8273e-16, 5.2609e-02, 3.6514e-01, 4.0798e-02, 6.9943e-01, -7.0055e-01, 3.5640e-01, -3.9202e-01, -1.3696e+00, 2.5837e+00, 1.5109e-16, -4.2993e-17, -8.9841e-17, -7.7655e-02, -5.7628e-02, -1.6491e-02, -2.3735e-01, 9.2090e-02, -1.5748e-01, 1.4530e-01, 1.6290e-01, -4.3583e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 4.3730e-02, 3.0801e-01, -1.8641e-01, 1.0358e-01, -1.2768e-03, -2.1376e-01, -9.9024e-02, 1.0211e-01, -1.1796e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		9.6361e-17, -6.6669e-16, 6.8905e-17, -4.6953e-16, -7.6137e-17, 2.5872e-16, 6.1573e-16, 1.0280e-15, 3.4585e-16, -6.0374e-30, -2.2376e-30, -7.1791e-30, 7.2978e-16, -1.2616e-15, 8.4375e-16, 2.2142e-16, -9.6295e-16, 5.0179e-16, 2.6626e-16, -7.2191e-16, 4.8659e-16, 3.3540e-30, -2.7957e-31, 7.7063e-31, -1.7563e-15, 3.2240e-15, -1.7803e-15, -2.9129e-15, 8.4049e-16, -1.3416e-17, -9.4688e-17, 2.3659e-16, -1.5098e-16, -3.2419e-31, 3.0118e-30, 7.3441e-31, 2.5693e-15, -1.9981e-15, 1.3729e-15, -1.4435e-15, -9.7966e-16, -2.7920e-16, -7.3923e-17, 7.9502e-17, -1.2151e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.0444e-15, 2.5816e-17, 9.0699e-16, 6.0341e-16, -4.4940e-16, 5.4906e-16, 7.0222e-17, 1.3283e-16, 2.4819e-17, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.5747e-16, 1.1552e-15, -3.4043e-16, -2.9733e-16, -5.4729e-16, -1.1084e-16, -9.6454e-16, -3.4987e-16, 4.2004e-16, -9.7699e-30, -5.1832e-30, -1.5480e-29, 3.2377e-15, -6.5209e-16, 1.5272e-15, 1.4091e-15, -9.4474e-18, -1.3516e-16, 8.6479e-16, 4.0715e-16, 2.7035e-16, 5.4649e-30, -6.7980e-31, 1.5478e-30, -6.6541e-15, 3.7701e-15, -2.1296e-15, 3.2256e-15, 2.0845e-15, 3.8100e-17, -7.3725e-16, -1.3157e-16, 1.4496e-16, 5.0544e-32, 4.1289e-30, 5.3983e-31, 3.2047e-15, -2.5155e-15, 1.8170e-15, -5.1872e-16, -3.9651e-16, -9.4988e-17, -2.3546e-16, 2.6763e-16, -1.6275e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.7422e-15, 6.4908e-16, -1.1731e-15, -1.5970e-16, -6.2595e-16, 5.4661e-17, -2.7626e-16, 1.4379e-16, -1.3548e-16, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.0873e-16, 6.8207e-16, 5.9068e-16, 2.0392e-15, 1.6772e-15, -1.6976e-15, -2.1667e-16, 4.9994e-16, 6.3508e-16, -4.4146e-30, -1.2062e-31, 3.1382e-30, 1.3042e-15, -1.7774e-15, -5.5399e-16, 2.8223e-15, 3.5051e-16, -3.2208e-16, -8.8582e-16, 2.0696e-15, -1.5537e-15, -3.9264e-31, 4.7627e-31, -7.5043e-31, -1.2670e-15, 1.0516e-15, 1.3682e-15, 2.4591e-15, 9.1396e-16, 4.6049e-17, -1.7332e-15, -5.0432e-16, 2.8632e-16, 1.7976e-30, -1.3165e-30, -1.4096e-30, -2.2985e-15, -5.2921e-16, -1.8963e-15, -1.7470e-15, -8.6749e-17, -3.4319e-16, -2.4714e-16, -2.0547e-17, -8.6734e-17, 0.0000e+00, 0.0000e+00, 0.0000e+00, 2.1240e-15, -3.8756e-16, 1.5510e-15, 4.4977e-16, 8.3772e-16, 1.1191e-16, 2.4170e-17, 1.2105e-16, -5.5492e-18, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		6.2324e-01, -7.3559e-01, -6.9731e-01, -6.2096e-01, -3.7786e-01, -2.6182e-02, 7.1648e-01, -1.9262e-01, -7.0246e-01, -9.6617e-15, -2.1846e-15, -2.0575e-14, 1.1889e+00, 6.3387e-02, 5.6060e-01, 3.4469e-01, 8.0855e-02, -2.0943e-01, 2.7842e-01, -3.8642e-01, 3.0457e-01, 5.4123e-15, -2.8245e-15, 3.2726e-15, -3.3993e+00, 1.1641e+00, -2.3408e+00, -4.9140e-01, 1.5947e-01, -5.7918e-03, -8.5392e-02, 1.8959e-01, -7.7655e-02, -1.9941e-15, 4.9856e-15, 2.7102e-15, 1.2736e+01, -2.3180e+00, 3.9352e+00, 1.4770e+00, -6.6384e-01, 6.2105e-01, 3.0571e-01, -3.1682e-02, 1.8580e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -2.4866e+00, 1.0374e+00, -1.3319e-01, -8.5991e-01, 6.1604e-01, -5.9314e-01, -4.0816e-01, -4.5817e-02, -1.8506e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.4295e-01, 7.6978e-01, 8.3519e-01, -1.6529e-01, -1.3590e-01, 7.1631e-02, 1.5819e-02, 1.3992e-01, 1.8886e-01, 9.0511e-15, -3.3265e-15, 6.3710e-15, 4.2514e-01, 4.0771e-02, -2.3754e-01, -9.5260e-02, -1.0068e-01, -1.1635e-01, 3.3197e-01, -5.0669e-01, 4.8914e-01, -3.0965e-15, -1.2537e-15, -2.3834e-15, 1.5934e+00, -3.5855e+00, -5.8331e-01, 4.0682e-01, -7.8567e-02, -9.2315e-03, -1.3757e-01, 7.7973e-02, -5.7628e-02, 1.2948e-15, -2.7167e-15, -3.2215e-16, -2.3180e+00, 1.1222e+01, -1.5684e+00, 5.2361e-01, 4.3151e-01, 1.0266e-01, 3.1524e-01, -7.2623e-02, 9.1743e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 7.6856e-01, -2.1719e+00, 7.5871e-01, 2.5256e-02, -3.6962e-01, 6.1417e-02, 1.0527e-01, -1.5068e-01, 2.6576e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.3783e-01, 1.0798e-01, -2.6741e-01, 5.3400e-02, -1.2468e-01, 1.2445e-01, 2.7001e-01, -3.9160e-01, -3.4700e-01, -2.4533e-15, 4.1737e-15, -1.0412e-14, 1.9283e-01, -2.4326e-01, 2.0730e-01, -5.8761e-01, -3.3021e-01, 2.8824e-01, 5.1299e-02, -1.3979e-01, 5.1900e-02, 8.9831e-18, -8.7362e-16, 7.0561e-16, 1.1473e+00, 1.4651e+00, -3.2172e+00, 5.0265e-02, 7.6522e-01, -5.1608e-03, -6.2622e-03, 4.2442e-02, -1.6491e-02, -1.7545e-15, 3.3413e-15, 1.7186e-15, 3.9352e+00, -1.5684e+00, 7.3084e+00, 4.1101e-01, -7.2972e-01, 6.7029e-03, 2.1022e-01, 1.9229e-01, -4.2530e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.8987e+00, -8.2720e-02, -2.3514e+00, -5.3470e-01, 3.6490e-01, -3.4778e-01, -1.3123e-01, 7.2582e-02, -6.6160e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-4.5662e-01, -3.2488e-02, 2.9372e-01, -1.0036e-01, 5.5071e-01, 3.3496e-01, 1.6070e-01, 1.1877e-01, -7.0114e-02, -3.0589e-15, 1.0133e-15, -4.8187e-15, -6.5668e-01, 2.7624e-01, -5.6315e-02, -1.0351e+00, 3.5930e-02, 3.5090e-01, -8.1504e-01, 4.1766e-01, -6.1237e-01, 6.8390e-16, -4.2991e-16, 9.8526e-16, -9.9204e-01, 2.6323e-01, -4.4997e-01, -9.8377e-01, 4.8362e-01, -1.9484e-02, -1.0141e-01, 4.2874e-01, -2.3735e-01, -7.1261e-16, -8.5896e-17, 6.1232e-16, 1.4770e+00, 5.2361e-01, 4.1101e-01, 1.3960e+01, 1.9725e+00, 2.7651e+00, 9.9511e-02, -3.1690e-01, 4.7697e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -7.6149e-01, 2.0815e-01, -3.4057e-01, -1.3215e+00, 2.9458e-01, -9.8775e-01, -6.5606e-01, 5.2960e-01, -3.7144e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.2564e-02, -2.3679e-01, 3.7231e-02, 1.0556e-01, 2.6957e-01, -1.5947e-01, 1.6471e-01, 1.5222e-01, -1.4498e-02, 8.9867e-16, -1.3632e-15, -1.9466e-16, 4.6277e-01, -3.4437e-01, 1.3868e-01, -1.5724e-01, -1.0056e-01, -1.9996e-01, -8.8143e-02, -1.4748e-01, 1.8732e-02, -2.4742e-16, -8.6135e-16, -1.0210e-15, -2.5525e-01, -3.4190e-02, -1.7081e-01, 2.6164e-01, -7.9666e-01, -1.5715e-01, -3.1703e-02, -3.2357e-01, 9.2090e-02, 8.3608e-16, -2.3370e-17, -2.3820e-16, -6.6384e-01, 4.3151e-01, -7.2972e-01, 1.9725e+00, 7.2777e+00, -2.6130e-01, -5.7352e-02, 1.8312e-01, 2.0877e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 2.8074e-01, -1.5834e-01, 4.8972e-01, 1.0016e-02, -4.3021e-01, -3.3657e-01, 2.1847e-01, -2.5126e-01, 1.2886e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-7.1402e-02, -6.0452e-02, 4.6564e-02, -2.4823e-02, 9.3515e-02, 3.7192e-02, 1.2836e-02, 7.0006e-02, -2.7268e-03, -1.3468e-15, 3.6574e-16, -1.0760e-15, -1.6960e-01, 1.4033e-01, -1.1704e-02, -2.4734e-01, 3.6680e-02, -5.2526e-02, -3.5130e-01, 1.1460e-01, -3.0075e-01, 1.8916e-16, -5.3471e-17, 4.0367e-16, -2.3622e-01, 5.6294e-02, 1.0669e-01, -6.6653e-02, 7.4942e-02, -1.8164e-01, 8.3925e-02, 9.8480e-02, -1.5748e-01, -2.3762e-16, -1.0656e-16, 1.5068e-16, 6.2105e-01, 1.0266e-01, 6.7029e-03, 2.7651e+00, -2.6130e-01, 2.2318e+00, -1.7235e-01, 6.7190e-03, 4.8868e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -4.2952e-02, 4.4453e-02, -1.9293e-01, -1.5222e-01, 7.5640e-02, -4.1729e-01, -3.9157e-01, -1.1432e-01, -2.3897e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.8969e-02, -2.2232e-01, -8.8317e-02, -7.2247e-02, -4.7147e-02, 8.1245e-02, -1.3340e-03, -1.1432e-01, -3.6117e-02, 9.1899e-16, -5.1330e-16, 5.9116e-16, -3.1009e-01, 2.5641e-02, -4.4974e-02, 1.3070e-01, 1.7583e-01, -5.3191e-02, 1.0986e-01, 1.0204e-01, 1.2812e-01, -6.3535e-16, 7.3801e-16, -3.6574e-16, 2.5669e-01, -1.5586e-01, 1.9973e-01, -2.5093e-01, -1.1737e-01, 1.1807e-01, -2.0031e-01, -2.3392e-01, 1.4530e-01, -8.4951e-17, -1.8499e-16, 3.7631e-17, 3.0571e-01, 3.1524e-01, 2.1022e-01, 9.9511e-02, -5.7352e-02, -1.7235e-01, 4.5818e+00, -9.7235e-01, 7.1399e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -2.9785e-01, -2.4043e-01, -1.2238e-01, -2.0212e-01, -2.0690e-01, 1.8907e-02, 1.4322e-01, 3.2939e-01, -1.0991e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.9372e-02, 2.6429e-01, 4.7269e-02, -8.6600e-03, 1.2984e-01, -6.7999e-02, -1.8850e-01, -5.2929e-03, 1.5452e-01, 1.5147e-16, 1.3456e-15, -9.8325e-16, 2.0779e-02, 7.8790e-03, 2.8664e-02, -2.1136e-01, -1.4079e-01, 1.5338e-01, -2.2517e-02, -7.7122e-02, -8.0219e-03, 3.3579e-16, -7.5464e-16, 3.7724e-16, -1.4729e-01, 2.9272e-02, -1.5148e-01, 1.0621e-01, 8.0865e-02, 2.4791e-02, 2.1399e-02, -6.7030e-02, 1.6290e-01, -7.2562e-17, 1.8325e-16, 8.9682e-17, -3.1682e-02, -7.2623e-02, 1.9229e-01, -3.1690e-01, 1.8312e-01, 6.7190e-03, -9.7235e-01, 3.8047e+00, -1.2817e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 9.9136e-02, 9.7742e-02, -2.0594e-02, -3.2452e-01, -2.3384e-01, -5.4358e-02, -1.9497e-01, -4.3620e-01, -1.3373e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.3418e-02, -2.0660e-01, 1.5216e-02, -1.8417e-03, -7.5386e-03, -1.9903e-02, 5.0730e-02, 1.0069e-01, -1.0385e-01, -5.4985e-16, -6.2765e-16, 3.7023e-16, 7.8953e-03, 5.1422e-02, -1.4352e-02, 1.0133e-01, 6.6551e-02, -2.1692e-01, -9.1791e-02, 1.1976e-02, -1.1652e-01, -2.9429e-16, 4.6372e-16, -1.8634e-16, 1.3453e-01, -4.7531e-02, 6.8148e-03, 8.9242e-02, -1.9617e-01, -1.4911e-01, 8.7481e-02, 2.3852e-01, -4.3583e-01, 2.3184e-17, -1.2025e-16, -7.8416e-18, 1.8580e-01, 9.1743e-02, -4.2530e-02, 4.7697e-01, 2.0877e-02, 4.8868e-01, 7.1399e-01, -1.2817e+00, 2.3975e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 3.6231e-02, -3.0907e-02, -8.2197e-02, 2.1301e-01, -5.5950e-02, -2.7991e-01, -2.0784e-02, 1.1671e-01, -1.9759e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		1.0825e+00, -9.8582e-01, -6.3693e-01, 1.5250e-01, 4.3842e-01, -3.1872e-01, 1.4450e-01, 7.2625e-02, 5.5617e-01, -4.1953e-15, -3.0648e-15, 1.1952e-15, 9.2012e-01, -2.3105e-01, -5.4843e-01, -3.5175e-01, 9.9470e-02, -1.7828e-01, 6.3850e-01, -1.0969e-01, 4.3333e-01, -1.4669e-15, 3.2158e-16, -2.4958e-15, 6.4226e-01, 6.0945e-01, 1.5714e-01, -1.9437e-01, 8.0787e-01, 3.0233e-03, -2.3420e-01, 2.9182e-02, 4.3730e-02, 1.1719e-15, -9.9170e-16, -5.9145e-16, -2.4866e+00, 7.6856e-01, -1.8987e+00, -7.6149e-01, 2.8074e-01, -4.2952e-02, -2.9785e-01, 9.9136e-02, 3.6231e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.0188e+01, -7.8879e-03, 5.0340e+00, 6.9836e-01, -1.5649e+00, 9.1012e-01, 3.8266e-01, -8.1130e-02, 1.7030e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.5102e-01, 6.8863e-01, -7.5272e-01, 9.8348e-02, 1.8552e-01, 7.1171e-01, 1.1300e-01, -3.1756e-01, -1.8537e-01, -2.5028e-15, 1.5125e-15, -1.2410e-15, 6.8247e-01, 8.6926e-01, -4.1430e-01, 3.8380e-01, 5.2037e-02, 7.1747e-02, 7.4928e-02, 3.1381e-01, -8.1699e-02, 4.9829e-16, 1.0980e-15, 1.4573e-15, 3.6692e-01, -1.0437e-01, 1.0693e-01, -3.9144e-02, -2.3491e-01, 1.3572e-01, -2.8572e-01, -1.3436e-01, 3.0801e-01, -2.4747e-16, 7.4019e-16, -1.1806e-16, 1.0374e+00, -2.1719e+00, -8.2720e-02, 2.0815e-01, -1.5834e-01, 4.4453e-02, -2.4043e-01, 9.7742e-02, -3.0907e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -7.8879e-03, 6.6635e+00, -6.2458e-01, 3.2441e-01, 2.5892e-01, -5.0395e-01, -1.4046e-01, 2.7859e-02, -1.1486e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		6.3424e-02, -8.9873e-01, 1.9845e-02, 2.5492e-01, 3.9540e-01, -1.3393e-01, -5.8287e-02, -1.2837e-01, 3.2121e-01, -3.1273e-15, -2.3462e-15, -6.1049e-16, -2.3349e-01, -5.2970e-01, 3.0828e-02, -1.4068e-01, 3.5280e-01, -3.6910e-01, 3.5394e-01, -4.3079e-01, 2.8971e-01, -2.7801e-16, -9.0076e-16, -1.5190e-15, -3.7571e-01, 4.8598e-01, -1.8028e-01, -2.8038e-01, 6.8085e-01, -1.8688e-01, -1.6440e-01, 7.4996e-03, -1.8641e-01, 6.4702e-16, -7.5444e-16, -6.7063e-17, -1.3319e-01, 7.5871e-01, -2.3514e+00, -3.4057e-01, 4.8972e-01, -1.9293e-01, -1.2238e-01, -2.0594e-02, -8.2197e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 5.0340e+00, -6.2458e-01, 5.8935e+00, 5.8278e-01, -6.1117e-01, 2.9840e-01, 7.0988e-02, -6.4443e-02, 1.5932e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-2.3049e-01, 2.0994e-01, 2.9858e-01, 3.4457e-02, -1.9184e-01, 1.6769e-01, 1.3319e-01, 1.2791e-02, -2.4834e-01, 6.7962e-16, -2.6527e-15, 4.7573e-15, 4.9035e-02, 5.1637e-01, -1.1308e-01, 5.0227e-01, -2.1074e-02, 2.7339e-01, 1.1379e-01, -1.7280e-02, 5.2140e-02, -7.8789e-17, -6.8349e-16, -7.0137e-16, 1.0559e-01, 3.8364e-01, 4.4999e-02, -5.8698e-01, 9.5617e-02, 1.1803e-02, -2.9129e-01, -5.5631e-02, 1.0358e-01, 4.3702e-16, -5.8122e-17, -3.4188e-16, -8.5991e-01, 2.5256e-02, -5.3470e-01, -1.3215e+00, 1.0016e-02, -1.5222e-01, -2.0212e-01, -3.2452e-01, 2.1301e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 6.9836e-01, 3.2441e-01, 5.8278e-01, 6.5401e+00, 1.5664e-01, 2.0288e+00, 3.1838e-01, 2.7836e-01, 1.2402e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-1.2833e-02, -9.2535e-01, 1.5179e-01, -2.7773e-01, 7.6035e-02, 4.3783e-01, 2.1445e-01, -1.3546e-01, -5.0368e-01, 1.1453e-16, -1.1987e-15, 8.2220e-16, -1.7378e-01, -7.4942e-01, -1.4442e-01, 1.0222e+00, 3.1345e-01, -2.3771e-01, -3.3512e-01, 3.8621e-02, -3.4783e-01, 6.7870e-16, -1.2223e-15, 3.6364e-16, 1.8932e-01, -3.3286e-01, 2.5212e-01, 3.2079e-01, -4.3152e-01, 1.2187e-01, -2.4468e-01, -5.4113e-02, -1.2768e-03, 1.4185e-16, -7.7888e-17, -1.3906e-16, 6.1604e-01, -3.6962e-01, 3.6490e-01, 2.9458e-01, -4.3021e-01, 7.5640e-02, -2.0690e-01, -2.3384e-01, -5.5950e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, -1.5649e+00, 2.5892e-01, -6.1117e-01, 1.5664e-01, 7.8246e+00, -1.4159e+00, 3.1131e-01, -2.2428e-01, 8.4371e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.5149e-01, 3.6545e-01, 1.6827e-01, 5.0920e-02, -1.1177e-01, -6.3743e-02, -4.6623e-02, 2.4428e-01, 4.6939e-02, 2.1539e-16, -8.5082e-16, 2.5759e-15, 2.1765e-01, 1.7798e-01, 1.0971e-01, -7.4709e-02, -1.0511e-01, -1.7238e-02, 1.2347e-02, 5.0524e-02, 1.7593e-02, -2.5419e-16, 1.0073e-16, -5.0415e-16, 1.3398e-01, 2.5556e-01, 5.8853e-02, -3.9079e-01, 6.3803e-02, -1.6197e-01, 9.5912e-02, 9.9229e-02, -2.1376e-01, 1.9330e-16, -9.5804e-17, -1.8269e-16, -5.9314e-01, 6.1417e-02, -3.4778e-01, -9.8775e-01, -3.3657e-01, -4.1729e-01, 1.8907e-02, -5.4358e-02, -2.7991e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 9.1012e-01, -5.0395e-01, 2.9840e-01, 2.0288e+00, -1.4159e+00, 3.6892e+00, 5.1415e-01, 1.7607e-01, -1.3284e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		3.3548e-02, 7.4480e-02, 1.5837e-01, -1.6759e-01, -8.9059e-02, 1.2318e-01, 1.1143e-01, -2.3274e-02, -1.1917e-01, 1.7831e-15, -1.8507e-15, 7.5733e-16, 3.8838e-02, 3.4297e-02, -7.5438e-02, -7.9123e-03, 1.0601e-01, 1.4897e-02, 1.3641e-01, -8.3200e-02, 2.2170e-01, 2.4802e-16, -1.2990e-16, -1.7079e-16, 1.5696e-01, 2.5702e-02, 1.1255e-01, -2.4441e-01, -2.8485e-01, 5.8441e-02, -9.1327e-02, 1.3871e-01, -9.9024e-02, 2.0683e-16, -1.2964e-16, -1.4945e-16, -4.0816e-01, 1.0527e-01, -1.3123e-01, -6.5606e-01, 2.1847e-01, -3.9157e-01, 1.4322e-01, -1.9497e-01, -2.0784e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00, 3.8266e-01, -1.4046e-01, 7.0988e-02, 3.1838e-01, 3.1131e-01, 5.1415e-01, 3.9827e+00, -1.2350e+00, 1.1941e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		2.8449e-02, -2.3556e-01, -2.6857e-02, 1.1129e-01, 6.2909e-02, 1.0087e-01, 9.7190e-02, 2.3567e-01, -1.1377e-01, -7.0031e-16, 3.4897e-16, 1.4346e-15, -1.1186e-01, -3.4108e-02, 2.6668e-02, 1.0704e-01, -3.7604e-02, -8.2564e-02, 1.0044e-01, -3.2512e-02, -1.0607e-02, -6.3737e-16, 2.4039e-16, -3.5592e-16, -1.7520e-02, 1.2156e-01, -6.0748e-02, -4.1534e-03, 7.9244e-01, -1.1494e-01, -9.7836e-02, -2.3567e-01, 1.0211e-01, -1.4757e-16, 4.9514e-17, 6.9562e-17, -4.5817e-02, -1.5068e-01, 7.2582e-02, 5.2960e-01, -2.5126e-01, -1.1432e-01, 3.2939e-01, -4.3620e-01, 1.1671e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, -8.1130e-02, 2.7859e-02, -6.4443e-02, 2.7836e-01, -2.2428e-01, 1.7607e-01, -1.2350e+00, 4.9929e+00, -1.5750e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		-4.4981e-02, 8.4561e-02, 2.0729e-01, -3.0032e-03, -1.6047e-02, 1.9219e-02, -7.1268e-02, -2.3458e-02, -2.7920e-02, 1.1346e-15, -7.2553e-16, -5.7678e-16, -8.4742e-02, 2.9605e-02, -1.0387e-02, -1.6751e-02, 3.0089e-02, -4.5474e-02, 4.4947e-03, -8.6581e-02, 1.0504e-01, 2.9173e-16, -2.2850e-16, 7.5843e-18, -2.0629e-02, 1.8995e-03, -1.9705e-01, -7.2792e-02, -2.1353e-01, -2.0086e-02, 4.2317e-02, 5.2988e-02, -1.1796e-01, 1.0762e-16, -8.5908e-17, -1.8798e-17, -1.8506e-01, 2.6576e-01, -6.6160e-02, -3.7144e-01, 1.2886e-02, -2.3897e-01, -1.0991e-01, -1.3373e-01, -1.9759e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 1.7030e-01, -1.1486e-01, 1.5932e-01, 1.2402e-01, 8.4371e-02, -1.3284e-01, 1.1941e+00, -1.5750e+00, 2.9363e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
		0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00};
	std::copy(A_data, A_data + 3600, totalm.hand_pose_prior_A.data());
	totalm.hand_pose_prior_A.transposeInPlace();

	file.close();

	// load PCA
	printf("Loading from: %s\n", pca_path.c_str());
	file.open(pca_path.c_str(), std::ifstream::in);
	file >> pca_root;

	initMatrix(totalm.m_meanshape, pca_root["mu"]);
	initMatrix(totalm.m_shapespace_Ds, pca_root["Ds"]);
	Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> temp;
	initMatrix(temp, pca_root["Uw1"]); // Uw1 is reduced to (:, :30)
	totalm.m_shapespace_u = temp.block(0, 0, 3*TotalModel::NUM_VERTICES, TotalModel::NUM_SHAPE_COEFFICIENTS);

	totalm.J_mu_ = totalm.m_J_reg * totalm.m_meanshape;
	totalm.dJdc_ = totalm.m_J_reg * totalm.m_shapespace_u;

	// load correspondence
	printf("Loading from: %s\n", correspondence_path.c_str());
	totalm.m_vertexCorresSources.clear();
	std::ifstream fin(correspondence_path.c_str());
	if (fin.is_open() == false)
	{
		printf("## Error: Failed in opening total correspondence file: %s\n", correspondence_path.c_str());
		return;
	}
	while (fin.eof() == false)
	{
		int target_vertex_index;	//index of vertex in total mesh (these are all in order)
		int source_mesh;		//body=0, face=1, rhand=2, lhand=3
		int source_v[3];	// vertex indices of corresponding triangle in the mesh given by "source_mesh"
		double source_w[3]; // barycentric weights for each of the 3 vertices
		fin >> target_vertex_index >> source_mesh >> source_v[0] >> source_v[1] >> source_v[2];			//indices are 0-based. 
		fin >> source_w[0] >> source_w[1] >> source_w[2];			//weight are zeros

		if (fin.eof())
			break;

		if(source_mesh ==0 )
			totalm.m_vertexCorresSources.push_back(TotalModelCorresUnit(CMeshModelInstance::MESH_TYPE_SMPL));
		else if (source_mesh == 1)
			totalm.m_vertexCorresSources.push_back(TotalModelCorresUnit(CMeshModelInstance::MESH_TYPE_FACE));
		else if (source_mesh == 2)
			totalm.m_vertexCorresSources.push_back(TotalModelCorresUnit(CMeshModelInstance::MESH_TYPE_RHAND));
		else if (source_mesh == 3)
			totalm.m_vertexCorresSources.push_back(TotalModelCorresUnit(CMeshModelInstance::MESH_TYPE_LHAND));
		else
		{
			printf("## ERROR:: Unknown type: %d\n", source_mesh);
			fin.close();
			return;
		}

		for(int i=0;i<3;++i)
		{
			if (source_w[i] >= 0.001)
			{
				totalm.m_vertexCorresSources.back().m_corresWeight.push_back(std::make_pair(source_v[i], source_w[i]));
			}
		}
	}

	const int NUM_FACE_POINTS = 11510;
	totalm.m_C_face2total.resize(TotalModel::NUM_VERTICES*3, NUM_FACE_POINTS * 3);
	totalm.m_C_face2total.setZero();

	std::vector<Eigen::Triplet<double> > A_IJV;
	A_IJV.reserve(NUM_FACE_POINTS * 3);

	for (auto v = 0u; v < totalm.m_vertexCorresSources.size(); ++v)
	{
		if (totalm.m_vertexCorresSources[v].m_sourceMeshType != CMeshModelInstance::MESH_TYPE_FACE)
			continue;

		for (auto j = 0u; j < totalm.m_vertexCorresSources[v].m_corresWeight.size(); ++j)
		{
			int sourceV_idx = totalm.m_vertexCorresSources[v].m_corresWeight[j].first;
			double sourceV_weight = totalm.m_vertexCorresSources[v].m_corresWeight[j].second;
			int totalModelV_idx = v;

			A_IJV.push_back(Eigen::Triplet<double>(3 * totalModelV_idx +0, 3 * sourceV_idx +0, sourceV_weight));
			A_IJV.push_back(Eigen::Triplet<double>(3 * totalModelV_idx +1, 3 * sourceV_idx +1, sourceV_weight));
			A_IJV.push_back(Eigen::Triplet<double>(3 * totalModelV_idx +2, 3 * sourceV_idx +2, sourceV_weight));
		}
		//totalMeshOut.m_vertices[v] = totalMeshOut.m_vertices[v] + pos * 10;
	}
	totalm.m_C_face2total.setFromTriplets(A_IJV.begin(), A_IJV.end());
	totalm.m_C_face2total = totalm.m_C_face2total* 100.0; //100.0 to adjust scales

	totalm.m_dVdFaceEx = totalm.m_C_face2total * U_exp_;
	std::cout << totalm.m_dVdFaceEx.cols() << " " << totalm.m_dVdFaceEx.rows() << std::endl;

	printf("## Total Body model has been loaded\n");
}

void adam_reconstruct_Eulers(const TotalModel& totalm,
	const double *parm_coeffs,
	const double *parm_pose_eulers,
	const double *parm_faceEx_coeffs,
	double *outVerts,
	Eigen::VectorXd &transforms,
	const bool euler)
{
	using namespace smpl;
	using namespace Eigen;
	Map< const Matrix<double, Dynamic, 1> > c(parm_coeffs, TotalModel::NUM_SHAPE_COEFFICIENTS);

	Matrix<double, Dynamic, Dynamic, RowMajor> Vt(TotalModel::NUM_VERTICES, 3);
	Map< Matrix<double, Dynamic, 1> > Vt_vec(Vt.data(), 3 * TotalModel::NUM_VERTICES);

	Map< Matrix<double, Dynamic, Dynamic, RowMajor> > outV(outVerts, TotalModel::NUM_VERTICES, 3);

	Vt_vec = totalm.m_meanshape + totalm.m_shapespace_u*c;

	Matrix<double, TotalModel::NUM_JOINTS, 3, RowMajor> J;
	Map< Matrix<double, Dynamic, 1> > J_vec(J.data(), TotalModel::NUM_JOINTS * 3);
	J_vec = totalm.m_J_reg * Vt_vec;

	transforms.resize(3 * TotalModel::NUM_JOINTS * 4);
	VectorXd transforms_joint(3 * TotalModel::NUM_JOINTS * 4 + 3 * TotalModel::NUM_JOINTS); // the first part is transform, the second part is outJoint

	const int num_t = (TotalModel::NUM_JOINTS) * 3 * 4;
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTrdP((TotalModel::NUM_JOINTS) * 3 * 5, 3 * TotalModel::NUM_JOINTS);
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTrdJ((TotalModel::NUM_JOINTS) * 3 * 5, 3 * TotalModel::NUM_JOINTS);

	ceres::AutoDiffCostFunction<PoseToTransformsNoLR_Eulers_adamModel,
		(TotalModel::NUM_JOINTS) * 3 * 5,
		(TotalModel::NUM_JOINTS) * 3,
		(TotalModel::NUM_JOINTS) * 3> p2t(new PoseToTransformsNoLR_Eulers_adamModel(totalm, euler));
	const double * parameters[2] = { parm_pose_eulers, J.data() };
	double * residuals = transforms_joint.data();
	p2t.Evaluate(parameters, residuals, nullptr);		//automatically compute residuals and jacobians (dTdP and dTdJ)

	transforms.block(0, 0, num_t, 1) = transforms_joint.block(0, 0, num_t, 1);

	Map< const Matrix<double, Dynamic, 1> > c_faceEx(parm_faceEx_coeffs, TotalModel::NUM_EXP_BASIS_COEFFICIENTS);
	Vt_vec = Vt_vec + totalm.m_dVdFaceEx * c_faceEx;		// m_C_face2total*facem.U_exp_
	
	adam_lbs(totalm, Vt_vec.data(), transforms, outVerts);
}

void adam_lbs(const TotalModel &totalm,
    const double *verts,
    const MatrixXdr& T,
    double *outVerts)
{
    const Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
        Vs(verts, TotalModel::NUM_VERTICES, 3);
    Eigen::Map< Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
        outV(outVerts, TotalModel::NUM_VERTICES, 3);

    const Eigen::Map<const Eigen::VectorXd> Tv(T.data(), T.rows()*T.cols());
    const auto* T_data = T.data();
    #pragma omp parallel
    {
        #pragma omp for
        for (int idv = 0; idv < TotalModel::NUM_VERTICES; idv++)
        {
            auto* outVrow_data = &outVerts[3*idv];
            outVrow_data[0] = 0; // outV(idv, 0)
            outVrow_data[1] = 0; // outV(idv, 1)
            outVrow_data[2] = 0; // outV(idv, 2)
            const auto* const Vsrow_data = &verts[3*idv];
            for (int idj = 0; idj < TotalModel::NUM_JOINTS; idj++)
            {
                const double w = totalm.m_blendW(idv, idj);
                if (w)
                {
                    const auto baseIndex = idj * 3 * 4;
                    const auto* const Trow_data = &T_data[baseIndex];
                    outVrow_data[0] += w*(Vsrow_data[0]*Trow_data[0]
                                          + Vsrow_data[1]*Trow_data[1]
                                          + Vsrow_data[2]*Trow_data[2]
                                          + Trow_data[3]);
                    outVrow_data[1] += w*(Vsrow_data[0]*Trow_data[4]
                                          + Vsrow_data[1]*Trow_data[5]
                                          + Vsrow_data[2]*Trow_data[6]
                                          + Trow_data[7]);
                    outVrow_data[2] += w*(Vsrow_data[0]*Trow_data[8]
                                          + Vsrow_data[1]*Trow_data[9]
                                          + Vsrow_data[2]*Trow_data[10]
                                          + Trow_data[11]);
                    // Original code
                    // for (int idd = 0; idd < 3; idd++)
                    // {
                    //     outV(idv, idd) += w*Vs(idv, 0)*Tv(idj * 3 * 4 + idd * 4 + 0);
                    //     outV(idv, idd) += w*Vs(idv, 1)*Tv(idj * 3 * 4 + idd * 4 + 1);
                    //     outV(idv, idd) += w*Vs(idv, 2)*Tv(idj * 3 * 4 + idd * 4 + 2);
                    //     outV(idv, idd) += w*Tv(idj * 3 * 4 + idd * 4 + 3);
                    // }
                }
            }
        }
    }
}

void adam_lbs(const TotalModel &smpl,
	const double *verts,
	const MatrixXdr& T,
	double *outVerts,		//output
	const MatrixXdr &dVsdc,
	const MatrixXdr &dTdP,
	const MatrixXdr &dTdc,
	MatrixXdr &dVdc,	//output
	MatrixXdr &dVdP)	//output
{
	using namespace Eigen;
	Map< const Matrix<double, Dynamic, Dynamic, RowMajor> >
		Vs(verts, TotalModel::NUM_VERTICES, 3);
	Map< Matrix<double, Dynamic, Dynamic, RowMajor> >
		outV(outVerts, TotalModel::NUM_VERTICES, 3);

	dVdP.resize(TotalModel::NUM_VERTICES * 3, TotalModel::NUM_JOINTS * 3);
	dVdc.resize(TotalModel::NUM_VERTICES * 3, TotalModel::NUM_SHAPE_COEFFICIENTS);
	dVdP.setZero();
	dVdc.setZero();

	Map< const VectorXd > Tv(T.data(), T.rows()*T.cols());
	#pragma omp parallel num_threads(12)
	{
		#pragma omp for
		for (int idv = 0; idv<TotalModel::NUM_VERTICES; idv++) {
			outV(idv, 0) = 0;
			outV(idv, 1) = 0;
			outV(idv, 2) = 0;
			for (int idj = 0; idj<TotalModel::NUM_JOINTS; idj++) {
				if (smpl.m_blendW(idv, idj)) {
					double w = smpl.m_blendW(idv, idj);
					for (int idd = 0; idd<3; idd++) {
						outV(idv, idd) += w*Vs(idv, 0)*Tv(idj * 3 * 4 + idd * 4 + 0);
						outV(idv, idd) += w*Vs(idv, 1)*Tv(idj * 3 * 4 + idd * 4 + 1);
						outV(idv, idd) += w*Vs(idv, 2)*Tv(idj * 3 * 4 + idd * 4 + 2);
						outV(idv, idd) += w*Tv(idj * 3 * 4 + idd * 4 + 3);

						// SMPLModel::NUM_JOINTS
						// The joint transforms only depend on their parents, not vice-versa.
						// (meaning dTdP is block lower-triangular).
						for (int idp = 0; idp<(idj + 1) * 3; idp++) {
							dVdP(idv * 3 + idd, idp) += w*Vs(idv, 0)*dTdP(idj * 3 * 4 + idd * 4 + 0, idp);
							dVdP(idv * 3 + idd, idp) += w*Vs(idv, 1)*dTdP(idj * 3 * 4 + idd * 4 + 1, idp);
							dVdP(idv * 3 + idd, idp) += w*Vs(idv, 2)*dTdP(idj * 3 * 4 + idd * 4 + 2, idp);
							dVdP(idv * 3 + idd, idp) += w*dTdP(idj * 3 * 4 + idd * 4 + 3, idp);
						}
					
						for (int idc = 0; idc<TotalModel::NUM_SHAPE_COEFFICIENTS; idc++) {
							dVdc(idv * 3 + idd, idc) += w*dVsdc(idv * 3 + 0, idc)*Tv(idj * 3 * 4 + idd * 4 + 0);
							dVdc(idv * 3 + idd, idc) += w*dVsdc(idv * 3 + 1, idc)*Tv(idj * 3 * 4 + idd * 4 + 1);
							dVdc(idv * 3 + idd, idc) += w*dVsdc(idv * 3 + 2, idc)*Tv(idj * 3 * 4 + idd * 4 + 2);
							dVdc(idv * 3 + idd, idc) += w*dTdc(idj * 3 * 4 + idd * 4 + 3, idc);
						}
					}
				}
			}
		}
		// std::cout << "max threads " << omp_get_max_threads() << std::endl;
		// std::cout << "num threads " << omp_get_num_threads() << std::endl;
	}
}

void LoadTotalModelFromObj(TotalModel &totalm, const std::string &path)
{
	using namespace std;
	using namespace cv;

	ifstream fin(path.c_str());
	
	if (fin.is_open() == false)
	{
		printf("## Error: Failed in opening total body model: %s\n", path.c_str());
		return;
	}
	char bufChar[512];
	totalm.m_vertices.resize(TotalModel::NUM_VERTICES, 3);
	totalm.m_uvs.resize(TotalModel::NUM_VERTICES, 2);		//note that we assume  NUM_UVS==NUM_VERTICES
	totalm.m_normals.resize(TotalModel::NUM_VERTICES, 3);
	totalm.m_faces.resize(TotalModel::NUM_FACES, 3);


	//In this obj file, UV and normals are in arbitrary order
	//Need to align this to vertices ordering by chekcing face
	vector<Point2d> uvs;
	vector<Point3d> normals;
	vector<Point3d> vertices;
	normals.reserve(TotalModel::NUM_VERTICES);
	uvs.reserve(19531);

	totalm.m_uvs.setZero();
	
	int verCnt = 0;
	// int uvCnt = 0;
	// int normalCnt = 0;
	int faceCnt = 0;
	while(fin.eof()==false)
	{
		fin >> bufChar;
		if (fin.eof())
			break;
		if (strcmp(bufChar, "v") == 0)
		{
			/*Point3d temp;
			fin >> temp.x >> temp.y >> temp.z;
			vertices.push_back(temp);*/
			fin >> totalm.m_vertices(verCnt, 0) >> totalm.m_vertices(verCnt, 1) >> totalm.m_vertices(verCnt, 2);
			verCnt++;
		}
		else if(strcmp(bufChar,"vt")==0)
		{
			Point2d temp;
			fin >> temp.x >> temp.y;
			uvs.push_back(temp);
			//fin >> totalm.m_uvs(uvCnt, 0) >> totalm.m_uvs(uvCnt, 1);
			//uvCnt++;
		}
		else if(strcmp(bufChar, "vn") == 0)
		{
			Point3d temp;
			fin >> temp.x >> temp.y >> temp.z;
			normals.push_back(temp);
			//fin >> totalm.m_normals(normalCnt, 0) >> totalm.m_normals(normalCnt, 1) >> totalm.m_normals(normalCnt, 2);
			//normalCnt++;
		}
		else if (strcmp(bufChar, "f") == 0)
		{
			for(int i=0;i<3;++i)
			{
				int vertexId, textureId, normalIdx;
				fin >> vertexId >>textureId >> normalIdx;		//v1/vt1/vn1
				//faces.push_back(temp);*/
				//if(i==0)
					//fin >> totalm.m_faces(faceCnt, 0) >> totalm.m_faces(faceCnt, 1) >> totalm.m_faces(faceCnt, 2);
				vertexId--;
				totalm.m_faces(faceCnt, i) = vertexId;			//from 1-based to 0 based

				textureId--; //from 1-based to 0 based
				totalm.m_uvs(vertexId, 0) = uvs[textureId].x;		//overlaid if there are multiple uvs for a vertex
				totalm.m_uvs(vertexId, 1) = uvs[textureId].y;
							
				normalIdx--; //from 1-based to 0 based
				totalm.m_normals(vertexId, 0) = normals[normalIdx].x;
				totalm.m_normals(vertexId, 1) = normals[normalIdx].y;
				totalm.m_normals(vertexId, 2) = normals[normalIdx].z;
			}
			faceCnt++;
		}
		else
		{
			printf("## Warning: unknown option: %s\n", bufChar);
			continue;
		}
	}
	totalm.m_bInit = true;
	fin.close();
	printf("Finishing loading Total Model\n");
}

void LoadModelColorFromObj(TotalModel &totalm, const std::string &path)
{
	totalm.m_colors.resize(TotalModel::NUM_VERTICES, 3);
	std::ifstream f(path.c_str());
	std::string str = "";
	for (uint i = 0; i < TotalModel::NUM_VERTICES; i++)
	{
		// read in until it get "v "
		while (str != "v")
			f >> str;
		f >> str; f >> str; f >> str;   // vert
		f >> totalm.m_colors(i, 0) >> totalm.m_colors(i, 1) >> totalm.m_colors(i, 2);
	}
	f.close();
}

void LoadCocoplusRegressor(TotalModel &totalm, const std::string &path)
{
	printf("Loading from: %s\n", path.c_str());
	std::ifstream file(path.c_str(), std::ifstream::in);
    Json::Value root;
    file >> root;
    file.close();
    initSparseMatrix(totalm.m_cocoplus_reg, root["cocoplus_regressor"]);
    totalm.m_cocoplus_reg.makeCompressed();
}

Eigen::VectorXd adam_reconstruct_withDerivative_eulers(const TotalModel &totalm,
	const double *parm_coeffs,
	const double *parm_pose_eulers,		//Euler pose (but the first joint's param is still angle axis to avoid gimbal lock)
	const double *parm_faceEx_coeffs,
	double *outVerts,
	MatrixXdr &dVdc,
	MatrixXdr &dVdP,
	MatrixXdr &dVdfc,
	MatrixXdr &dTJdc,
	MatrixXdr &dTJdP,
	bool joint_only,
	bool fit_face)
{
	using namespace smpl;
	using namespace Eigen;
	Map< const Matrix<double, Dynamic, 1> > c_bodyshape(parm_coeffs, TotalModel::NUM_SHAPE_COEFFICIENTS);

	Matrix<double, Dynamic, Dynamic, RowMajor> Vt(TotalModel::NUM_VERTICES, 3);
	Map< Matrix<double, Dynamic, 1> > Vt_vec(Vt.data(), 3 * TotalModel::NUM_VERTICES);
	Map< Matrix<double, Dynamic, Dynamic, RowMajor> > outV(outVerts, TotalModel::NUM_VERTICES, 3);

	Vt_vec = totalm.m_meanshape + totalm.m_shapespace_u*c_bodyshape;

	Matrix<double, TotalModel::NUM_JOINTS, 3, RowMajor> J;
	Map< Matrix<double, Dynamic, 1> > J_vec(J.data(), TotalModel::NUM_JOINTS * 3);
	J_vec = totalm.J_mu_ + totalm.dJdc_*c_bodyshape;

	const int num_t = (TotalModel::NUM_JOINTS) * 3 * 5;
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTrdP(num_t, 3 * TotalModel::NUM_JOINTS); // Tr consists of T and TJ
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTrdJ(num_t, 3 * TotalModel::NUM_JOINTS);
	VectorXd transforms_joint(3 * TotalModel::NUM_JOINTS * 4 + 3 * TotalModel::NUM_JOINTS); // the first part is transform, the second part is outJoint

	ceres::AutoDiffCostFunction<PoseToTransformsNoLR_Eulers_adamModel,
		(TotalModel::NUM_JOINTS) * 3 * 4 + 3 * TotalModel::NUM_JOINTS,
		(TotalModel::NUM_JOINTS) * 3,
		(TotalModel::NUM_JOINTS) * 3> p2t(new PoseToTransformsNoLR_Eulers_adamModel(totalm));
	const double * parameters[2] = { parm_pose_eulers, J.data() };
	double* residuals = transforms_joint.data();
	double* jacobians[2] = { dTrdP.data(), dTrdJ.data() };
	p2t.Evaluate(parameters, residuals, jacobians);		//automatically compute residuals and jacobians (dTdP and dTdJ)

	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTdP(3 * TotalModel::NUM_JOINTS * 4, 3 * TotalModel::NUM_JOINTS);
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTdJ(3 * TotalModel::NUM_JOINTS * 4, 3 * TotalModel::NUM_JOINTS);
	dTdP = dTrdP.block(0, 0, 3 * TotalModel::NUM_JOINTS * 4, 3 * TotalModel::NUM_JOINTS);
	dTdJ = dTrdJ.block(0, 0, 3 * TotalModel::NUM_JOINTS * 4, 3 * TotalModel::NUM_JOINTS);

	dTJdP = dTrdP.block(3 * TotalModel::NUM_JOINTS * 4, 0, 3 * TotalModel::NUM_JOINTS, 3 * TotalModel::NUM_JOINTS);
	Matrix<double, Dynamic, 3 * TotalModel::NUM_JOINTS, RowMajor> dTJdJ =
		dTrdP.block(3 * TotalModel::NUM_JOINTS * 4, 0, 3 * TotalModel::NUM_JOINTS, 3 * TotalModel::NUM_JOINTS);
	dTJdc = dTJdJ * totalm.dJdc_;

	//Apply Face here
	if (fit_face)
	{
		Map< const Matrix<double, Dynamic, 1> > c_faceEx(parm_faceEx_coeffs, TotalModel::NUM_EXP_BASIS_COEFFICIENTS);
		Vt_vec = Vt_vec + totalm.m_dVdFaceEx * c_faceEx;		// m_C_face2total*facem.U_exp_
	}

	VectorXd transforms = transforms_joint.block(0, 0, 3 * TotalModel::NUM_JOINTS * 4, 1);
	VectorXd outJoint = transforms_joint.block(3 * TotalModel::NUM_JOINTS * 4, 0, 3 * TotalModel::NUM_JOINTS, 1);

	Matrix<double, Dynamic, TotalModel::NUM_SHAPE_COEFFICIENTS, RowMajor> dTdc = dTdJ * totalm.dJdc_;
	if (!joint_only)
	{
		adam_lbs(totalm, Vt_vec.data(), transforms, outVerts, totalm.m_shapespace_u, dTdP, dTdc, dVdc, dVdP);

		if (fit_face)
		{
			//Apply transformation for face vertices
			#pragma omp parallel for
			for (int idv = 0; idv < TotalModel::NUM_VERTICES; idv++) 
			{
				int idj = 15;
				{
					for (int idd = 0; idd < 3; idd++) 
					{
						for (int idc = 0; idc < TotalModel::NUM_EXP_BASIS_COEFFICIENTS; idc++) 
						{
							dVdfc(idv * 3 + idd, idc) = totalm.m_dVdFaceEx(idv * 3 + 0, idc) * transforms(idj * 3 * 4 + idd * 4 + 0);
							dVdfc(idv * 3 + idd, idc) += totalm.m_dVdFaceEx(idv * 3 + 1, idc) * transforms(idj * 3 * 4 + idd * 4 + 1);
							dVdfc(idv * 3 + idd, idc) += totalm.m_dVdFaceEx(idv * 3 + 2, idc) * transforms(idj * 3 * 4 + idd * 4 + 2);
						}
					}
				}
			}
		}
	}
	return outJoint;
}

void adam_reconstruct_Eulers_Fast(const TotalModel& totalm,
	const Eigen::Matrix<double, Eigen::Dynamic, 1> &Vt_vec,
	const Eigen::Matrix<double, Eigen::Dynamic, 1> &J0_vec,
	const double *parm_pose_eulers,
	const double *parm_faceEx_coeffs,
	double *outVerts,
	Eigen::VectorXd &transforms)
{
// const auto start1 = std::chrono::high_resolution_clock::now();
    using namespace smpl;

    transforms.resize(3 * TotalModel::NUM_JOINTS * 4);
    Eigen::VectorXd transforms_joint(3 * TotalModel::NUM_JOINTS * 4 + 3 * TotalModel::NUM_JOINTS); // the first part is transform, the second part is outJoint

// const auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start1).count();
// const auto start2 = std::chrono::high_resolution_clock::now();
    const int num_t = (TotalModel::NUM_JOINTS) * 3 * 4;
    Eigen::Matrix<double, Eigen::Dynamic, 3 * TotalModel::NUM_JOINTS, Eigen::RowMajor> dTrdP((TotalModel::NUM_JOINTS) * 3 * 5, 3 * TotalModel::NUM_JOINTS);
    Eigen::Matrix<double, Eigen::Dynamic, 3 * TotalModel::NUM_JOINTS, Eigen::RowMajor> dTrdJ((TotalModel::NUM_JOINTS) * 3 * 5, 3 * TotalModel::NUM_JOINTS);

// const auto duration2 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start2).count();
// const auto start3 = std::chrono::high_resolution_clock::now();
    ceres::AutoDiffCostFunction<PoseToTransformsNoLR_Eulers_adamModel,
        (TotalModel::NUM_JOINTS) * 3 * 5,
        (TotalModel::NUM_JOINTS) * 3,
        (TotalModel::NUM_JOINTS) * 3> p2t(new PoseToTransformsNoLR_Eulers_adamModel(totalm));
    const double * parameters[2] = { parm_pose_eulers, J0_vec.data() };
    double * residuals = transforms_joint.data();
// const auto duration3 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start3).count();
// const auto start4 = std::chrono::high_resolution_clock::now();
    p2t.Evaluate(parameters, residuals, nullptr);       //automatically compute residuals and jacobians (dTdP and dTdJ)

// const auto duration4 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start4).count();
// const auto start5 = std::chrono::high_resolution_clock::now();
    transforms.block(0, 0, num_t, 1) = transforms_joint.block(0, 0, num_t, 1);

// const auto duration5 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start5).count();
// const auto start6 = std::chrono::high_resolution_clock::now();
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> Vt_with_face(TotalModel::NUM_VERTICES, 3);
    Eigen::Map< Eigen::Matrix<double, Eigen::Dynamic, 1> > Vt_vec_with_face(Vt_with_face.data(), 3 * TotalModel::NUM_VERTICES);
    Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, 1> > c_faceEx(parm_faceEx_coeffs, TotalModel::NUM_EXP_BASIS_COEFFICIENTS);
// const auto duration6 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start6).count();
// const auto start7 = std::chrono::high_resolution_clock::now();
    Vt_vec_with_face = Vt_vec + totalm.m_dVdFaceEx * c_faceEx;      // m_C_face2total*facem.U_exp_

// const auto duration7 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start7).count();
// const auto start8 = std::chrono::high_resolution_clock::now();
    adam_lbs(totalm, Vt_vec_with_face.data(), transforms, outVerts);
// const auto duration8 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start8).count();
// std::cout << __FILE__ << " " << duration1 * 1e-6 << " 1\n"
//           << __FILE__ << " " << duration2 * 1e-6 << " 2\n"
//           << __FILE__ << " " << duration3 * 1e-6 << " 3\n"
//           << __FILE__ << " " << duration4 * 1e-6 << " 4\n"
//           << __FILE__ << " " << duration5 * 1e-6 << " 5\n"
//           << __FILE__ << " " << duration6 * 1e-6 << " 6\n"
//           << __FILE__ << " " << duration7 * 1e-6 << " 7\n"
//           << __FILE__ << " " << duration8 * 1e-6 << " 8\n" << std::endl;
}

int write_adam_obj(const CMeshModelInstance& mesh, const char* filename)
{
	assert(mesh.m_meshType == CMeshModelInstance::MESH_TYPE_ADAM);
	std::ofstream f(filename);
	if (!f.good())
	{
		std::cerr << "Cannot write Adam mesh to " << filename << std::endl;
		return 1;
	}
	for (auto i = 0u; i < TotalModel::NUM_VERTICES; i++)
		f << "v " << mesh.m_vertices[i].x / 100 << " "
				 << mesh.m_vertices[i].y / 100 << " "
				 << mesh.m_vertices[i].z / 100 << std::endl;
	assert(mesh.m_face_vertexIndices.size() % 3 == 0);
	for (auto i = 0u; i < mesh.m_face_vertexIndices.size() / 3; i++)
	f << "f " << mesh.m_face_vertexIndices[3 * i + 0] + 1 << " "
			 << mesh.m_face_vertexIndices[3 * i + 1] + 1 << " "
			 << mesh.m_face_vertexIndices[3 * i + 2] + 1 << std::endl;
	f.close();
	return 0;
}